diff --git a/RespectU.xcodeproj/project.pbxproj b/RespectU.xcodeproj/project.pbxproj index e1a9b8d..9274289 100644 --- a/RespectU.xcodeproj/project.pbxproj +++ b/RespectU.xcodeproj/project.pbxproj @@ -26,6 +26,7 @@ 16E72F47E46466C1D0F72348BC1734D2 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7994394D253D83388739913632BF52F4 /* Button.swift */; }; 1722D64EEA474AA4DB6530A17DA20635 /* TrophyTechnika3TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A875376A5EBE583D9D47E2CCA367EB4F /* TrophyTechnika3TableViewController.swift */; }; 1914B51E2236B3E500BA057E /* SearchRecordDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1914B51D2236B3E500BA057E /* SearchRecordDetail.swift */; }; + 1914B520223805BD00BA057E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1914B51F223805BD00BA057E /* Persistence.swift */; }; 1B7BDC0518E8261BB7E114B238485E0D /* Double+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0A70ADF02A515C554A2A7F65D04D0 /* Double+.swift */; }; 1C4D888E2BECAA7E7447EC6E493D700E /* TrophyBSTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2415AABC509E942301DF3589F55F8 /* TrophyBSTableViewController.swift */; }; 1D5A93ADB7E0551D8265EC21D90E8114 /* Note.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AF510989C994AF286BAC6EFC98F3D86 /* Note.swift */; }; @@ -255,6 +256,7 @@ 181F3BF12F13DC015494221C8902B980 /* AchievementResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchievementResponse.swift; sourceTree = ""; }; 18449AAA9B8578063135A1485D123683 /* AchievementNoteTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AchievementNoteTableViewController.swift; sourceTree = ""; }; 1914B51D2236B3E500BA057E /* SearchRecordDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecordDetail.swift; sourceTree = ""; }; + 1914B51F223805BD00BA057E /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; 1B070570A49E0EE97FB9D7A7BEE9915B /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = ""; }; 1EC376E253CB7630E7BAC771AB75FC10 /* APIService+Tip.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Tip.swift"; sourceTree = ""; }; 1FD55BA517A60A14D8EC54ACB1C7B9D4 /* Pods-RespectU.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RespectU.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RespectU/Pods-RespectU.debug.xcconfig"; sourceTree = ""; }; @@ -684,6 +686,7 @@ children = ( 3C37ECC78732D6E4E089B5B5F40D5C39 /* Realm */, 2AA94CA525D5326C0F9292D848B27357 /* Response */, + 1914B51F223805BD00BA057E /* Persistence.swift */, ); path = Models; sourceTree = ""; @@ -1111,6 +1114,7 @@ C49BDBE7974F6333739B639CFBC5DB8A /* BaseViewController.swift in Sources */, 16E72F47E46466C1D0F72348BC1734D2 /* Button.swift in Sources */, 94382F584F379628F8CCCEEF51AA8C23 /* CAGradientLayer+.swift in Sources */, + 1914B520223805BD00BA057E /* Persistence.swift in Sources */, 36105E909ADA369CB7D0D1B675FED1F4 /* Difficulty.swift in Sources */, 1B7BDC0518E8261BB7E114B238485E0D /* Double+.swift in Sources */, 53DC6066E155D2567781E494547956C9 /* DownloadViewController.swift in Sources */, diff --git a/RespectU/Resources/SwiftGen/Strings.swift b/RespectU/Resources/SwiftGen/Strings.swift index 83f87ee..955a4b4 100644 --- a/RespectU/Resources/SwiftGen/Strings.swift +++ b/RespectU/Resources/SwiftGen/Strings.swift @@ -21,12 +21,6 @@ internal enum L10n { internal static let _5BNORMALSeeker47CombosBREAKFullComboTrophyEarned = L10n.tr("Localizable", "5B NORMAL [Seeker]\n47 Combos -> BREAK -> Full Combo -> Trophy Earned") /// 777콤보 달성하기 internal static let _777Combos = L10n.tr("Localizable", "777 Combos") - /// 정확도 - internal static let accuracy = L10n.tr("Localizable", "ACCURACY") - /// 정확도 - internal static let accuracy = L10n.tr("Localizable", "Accuracy") - /// 도전과제 - internal static let achievement = L10n.tr("Localizable", "ACHIEVEMENT") /// 도전과제 internal static let achievement = L10n.tr("Localizable", "Achievement") /// 오름차순 @@ -45,8 +39,6 @@ internal enum L10n { internal static let changeBPMDefault = L10n.tr("Localizable", "Change BPM Default") /// 네트워크 상태를 확인하세요. internal static let checkYourNetworkStatus = L10n.tr("Localizable", "Check your network status.") - /// 준비중 - internal static let comingSoon = L10n.tr("Localizable", "Coming soon") /// 준비중입니다. internal static let comingSoon = L10n.tr("Localizable", "Coming soon.") /// 크레딧 @@ -169,8 +161,6 @@ internal enum L10n { internal static let normalDesc = L10n.tr("Localizable", "NORMAL / DESC") /// 비고 internal static let note = L10n.tr("Localizable", "NOTE") - /// 비고 - internal static let note = L10n.tr("Localizable", "Note") /// 알림 internal static let notification = L10n.tr("Localizable", "Notification") /// 확인 @@ -196,17 +186,15 @@ internal enum L10n { /// 점 internal static let point = L10n.tr("Localizable", "Point") /// 랭크 - internal static let rank = L10n.tr("Localizable", "Rank") - /// 랭크 internal static let rank = L10n.tr("Localizable", "RANK") /// 랭킹 internal static let ranking = L10n.tr("Localizable", "Ranking") - /// 정확도 - internal static let rate = L10n.tr("Localizable", "Rate") /// 정확도 범위 (%) internal static let rateRange = L10n.tr("Localizable", "Rate Range (%)") /// 앱 평가하기 internal static let rateThisApp = L10n.tr("Localizable", "Rate This App") + /// 정확도 + internal static let rating = L10n.tr("Localizable", "RATING") /// 제거 internal static let remove = L10n.tr("Localizable", "Remove") /// 검색 @@ -293,19 +281,19 @@ internal enum L10n { internal static let toResetTheValueDoNotEnterAnyValues = L10n.tr("Localizable", "Enter the rate.\nTo reset the value, do not enter any values.") } - internal enum InputYourAccuracy { + internal enum InputYourRate { /// 정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요. - internal static let toResetTheValueDoNotEnterAnyValues = L10n.tr("Localizable", "Input your accuracy.\nTo reset the value, do not enter any values.") + internal static let toResetTheValueDoNotEnterAnyValues = L10n.tr("Localizable", "Input your rate.\nTo reset the value, do not enter any values.") } - internal enum InputYourRate { + internal enum InputYourRating { /// 정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요. - internal static let toResetTheValueDoNotEnterAnyValues = L10n.tr("Localizable", "Input your rate.\nTo reset the value, do not enter any values.") + internal static let toResetTheValueDoNotEnterAnyValues = L10n.tr("Localizable", "Input your rating.\nTo reset the value, do not enter any values.") } internal enum ThereIsNewData { /// 새로운 데이터가 있습니다.\n"서버에서 다운로드하기"로 이동하여 최신 데이터로 업데이트하세요. - internal static let goToDownloadingFromTheServerAndUpdateToTheLatestData = L10n.tr("Localizable", "There is new data.\nGo to "Downloading from the server" and update to the latest data.") + internal static let goToDownloadingFromTheServerAndUpdateToTheLatestData = L10n.tr("Localizable", "There is new data.\nGo to [Downloading from the server] and update to the latest data.") } } // swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length diff --git a/RespectU/Resources/ko.lproj/Localizable.strings b/RespectU/Resources/ko.lproj/Localizable.strings index 7d793c1..d3b9311 100644 --- a/RespectU/Resources/ko.lproj/Localizable.strings +++ b/RespectU/Resources/ko.lproj/Localizable.strings @@ -1,4 +1,4 @@ -/* +/* Localizable.strings RespectU @@ -26,18 +26,14 @@ "Performance" = "성과"; "Performance Record" = "성과 기록"; "RANK" = "랭크"; -"Rank" = "랭크"; -"Rate" = "정확도"; -"Input your rate.\nTo reset the value, do not enter any values." = "정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요."; -"ACCURACY" = "정확도"; -"Accuracy" = "정확도"; +"RATING" = "정확도"; "NOTE" = "비고"; -"Note" = "비고"; +"Input your rate.\nTo reset the value, do not enter any values." = "정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요."; "No Pattern" = "패턴 없음"; "My Record" = "내 기록"; "PATTERNS" = "패턴"; "AVERAGE" = "평균 정확도"; -"Input your accuracy.\nTo reset the value, do not enter any values." = "정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요."; +"Input your rating.\nTo reset the value, do not enter any values." = "정확도를 입력하세요.\n값을 초기화하려면 어떠한 값도 입력하지 마세요."; "Select your rank." = "랭크를 선택하세요."; "Select your note." = "비고를 선택하세요."; @@ -52,7 +48,6 @@ "Unlock (ACHIEVEMENT)" = "해금 (도전과제)"; "Unlock (MISSION)" = "해금 (미션)"; -"ACHIEVEMENT" = "도전과제"; "My Favorite Button" = "주 버튼 설정"; "The information displayed on the first run screen depends on the setting value." = "설정값에 따라 첫 실행 화면에 표시되는 정보가 달라집니다."; @@ -98,7 +93,6 @@ "Nickname Setting" = "닉네임 설정"; "Enter your nickname." = "닉네임을 입력해 주세요."; "Point" = "점"; -"Coming soon" = "준비중"; "Summary" = "요약"; "Graph" = "그래프"; "MAX COMBO Failure" = "MAX COMBO 실패"; @@ -146,10 +140,7 @@ "Store recorded performance information on the server." = "기록한 성과 정보를 서버에 저장합니다."; "If there is no data on the server, the recorded performance information can be initialized." = "서버에 데이터가 없는 경우 기록한 성과 정보가 초기화될 수 있습니다."; "Warning" = "경고"; -"There is new data.\nGo to \"Downloading from the server\" and update to the latest data." = "새로운 데이터가 있습니다.\n\"서버에서 다운로드하기\"로 이동하여 최신 데이터로 업데이트하세요."; -"Rank" = "랭크"; -"Rate" = "정확도"; -"Note" = "비고"; +"There is new data.\nGo to [Downloading from the server] and update to the latest data." = "새로운 데이터가 있습니다.\n\"서버에서 다운로드하기\"로 이동하여 최신 데이터로 업데이트하세요."; "Select the note." = "비고를 선택하세요."; "Select the rank." = "랭크를 선택하세요."; "Enter the rate.\nTo reset the value, do not enter any values." = "정확도를 입력하세요.\n초기화하려면 아무 값도 입력하지 마세요."; diff --git a/RespectU/Sources/Common/MissionSection.swift b/RespectU/Sources/Common/MissionSection.swift index 5cad326..de47412 100644 --- a/RespectU/Sources/Common/MissionSection.swift +++ b/RespectU/Sources/Common/MissionSection.swift @@ -6,6 +6,8 @@ // Copyright © 2018년 Presto. All rights reserved. // +import UIKit + /// The `enum` that defines each mission sections. enum MissionSection { diff --git a/RespectU/Sources/Extension/String+.swift b/RespectU/Sources/Extension/String+.swift index 3573f9d..57d5b69 100644 --- a/RespectU/Sources/Extension/String+.swift +++ b/RespectU/Sources/Extension/String+.swift @@ -14,4 +14,57 @@ extension String { var localized: String { return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") } + + func missionGradient(_ direction: GradientDirection) -> CAGradientLayer? { + let startPoint = direction == .horizontal ? CGPoint(x: 0, y: 0.5) : CGPoint(x: 0.5, y: 0) + let endPoint = direction == .horizontal ? CGPoint(x: 1, y: 0.5) : CGPoint(x: 0.5, y: 1) + switch self { + case MissionSection.Respect.departure: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.137254902, green: 0.6549019608, blue: 0.3921568627, alpha: 1), #colorLiteral(red: 0.2431372549, green: 0.8235294118, blue: 0.8274509804, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.clubRoad645: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.1568627451, green: 0.6431372549, blue: 0.7725490196, alpha: 1), #colorLiteral(red: 0.2352941176, green: 0.8235294118, blue: 0.8, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.maxTheater: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.5176470588, green: 0.737254902, blue: 0.5019607843, alpha: 1), #colorLiteral(red: 0.2941176471, green: 0.7137254902, blue: 0.9176470588, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.anotherWorld: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.2156862745, green: 0.6392156863, blue: 0.7098039216, alpha: 1), #colorLiteral(red: 0.3215686275, green: 0.537254902, blue: 0.9333333333, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.backStage: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.631372549, green: 0.4117647059, blue: 0.9254901961, alpha: 1), #colorLiteral(red: 0.3450980392, green: 0.431372549, blue: 0.937254902, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.chaosTheory: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.6705882353, green: 0.3254901961, blue: 0.7725490196, alpha: 1), #colorLiteral(red: 0.5294117647, green: 0.3647058824, blue: 0.9764705882, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.soundLab: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.7098039216, green: 0.3294117647, blue: 0.8941176471, alpha: 1), #colorLiteral(red: 0.7568627451, green: 0.5529411765, blue: 0.3725490196, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.visualizer: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.7294117647, green: 0.3137254902, blue: 0.9254901961, alpha: 1), #colorLiteral(red: 0.9843137255, green: 0.4078431373, blue: 0.8156862745, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.developers: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.6392156863, green: 0.2784313725, blue: 0.6901960784, alpha: 1), #colorLiteral(red: 0.9803921569, green: 0.4470588235, blue: 0.4392156863, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Respect.destination: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.5921568627, green: 0.2588235294, blue: 0.2588235294, alpha: 1), #colorLiteral(red: 0.6470588235, green: 0.06274509804, blue: 0.1803921569, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Trilogy.tSide: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.2980392157, green: 0.337254902, blue: 0.9843137255, alpha: 1), #colorLiteral(red: 0.4, green: 0.6980392157, blue: 0.9764705882, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Trilogy.rSide: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.2941176471, green: 0.337254902, blue: 0.9843137255, alpha: 1), #colorLiteral(red: 0.5882352941, green: 0.4352941176, blue: 0.9568627451, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.CE.electronicCity: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.2509803922, green: 0.2352941176, blue: 0.1960784314, alpha: 1), #colorLiteral(red: 0.8352941176, green: 0.7254901961, blue: 0.2235294118, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.CE.metropolis: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.9254901961, green: 0.6980392157, blue: 0.2509803922, alpha: 1), #colorLiteral(red: 0.6274509804, green: 0.4784313725, blue: 0.7450980392, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Technika1.platinumMixing: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.09803921569, green: 0.1882352941, blue: 0.2980392157, alpha: 1), #colorLiteral(red: 0.5490196078, green: 0.6862745098, blue: 0.7921568627, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Technika1.technicalMixing: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.4, green: 0.07450980392, blue: 0.3803921569, alpha: 1), #colorLiteral(red: 0.8705882353, green: 0.2039215686, blue: 0.6392156863, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.BS.stylishPerformance: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.3411764706, green: 0.6274509804, blue: 0.9215686275, alpha: 1), #colorLiteral(red: 0.09803921569, green: 0.262745098, blue: 0.6784313725, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.BS.absoluteSound: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.8588235294, green: 0.2078431373, blue: 0.5960784314, alpha: 1), #colorLiteral(red: 0.3960784314, green: 0.05490196078, blue: 0.1960784314, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.LinkDisk.whiteDisk: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.6549019608, green: 0.03529411765, blue: 0.06274509804, alpha: 1), #colorLiteral(red: 0.9333333333, green: 0.7960784314, blue: 0.8117647059, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.LinkDisk.blackDisk: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.1333333333, green: 0.1176470588, blue: 0.1098039216, alpha: 1), #colorLiteral(red: 0.5921568627, green: 0.5411764706, blue: 0.3843137255, alpha: 1)], locations: [0, 0.5, 1]) + case MissionSection.Technika2.starMixing: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.537254902, green: 0.07058823529, blue: 0.5058823529, alpha: 1), #colorLiteral(red: 0.1058823529, green: 0.3882352941, blue: 0.6392156863, alpha: 1), #colorLiteral(red: 0.2470588235, green: 0.6588235294, blue: 0.1921568627, alpha: 1), #colorLiteral(red: 0.9333333333, green: 0.7333333333, blue: 0.1843137255, alpha: 1)], locations: [0, 0.25, 0.5, 0.75, 1]) + case MissionSection.Technika2.clubMixing: + return CAGradientLayer.makeGradient(startPoint: startPoint, endPoint: endPoint, colors: [#colorLiteral(red: 0.07843137255, green: 0.2470588235, blue: 0.6705882353, alpha: 1), #colorLiteral(red: 0.9843137255, green: 0.7960784314, blue: 0.1882352941, alpha: 1)], locations: [0, 0.5, 1]) + default: + return nil + } + } } diff --git a/RespectU/Sources/Models/Persistence.swift b/RespectU/Sources/Models/Persistence.swift new file mode 100644 index 0000000..2fc7652 --- /dev/null +++ b/RespectU/Sources/Models/Persistence.swift @@ -0,0 +1,49 @@ +// +// Persistence.swift +// RespectU +// +// Created by Presto on 13/03/2019. +// Copyright © 2019 Presto. All rights reserved. +// + +import Foundation + +struct Persistence { + + static var favoriteButton: Button { + get { + let buttonString = UserDefaults.standard.string(forKey: "favoriteButton") ?? "" + return Button(rawValue: buttonString) ?? .button4 + } + set { + UserDefaults.standard.do { + $0.set(newValue.rawValue, forKey: "favoriteButton") + $0.synchronize() + } + } + } + + static var nickname: String { + get { + return UserDefaults.standard.string(forKey: "nickname") ?? L10n.nicknameSetting + } + set { + UserDefaults.standard.do { + $0.set(newValue, forKey: "nickname") + $0.synchronize() + } + } + } + + static var numberOfLaunching: Int { + get { + return UserDefaults.standard.integer(forKey: "appOpenCount") + } + set { + UserDefaults.standard.do { + $0.set(newValue, forKey: "appOpenCount") + $0.synchronize() + } + } + } +} diff --git a/RespectU/Sources/Utils/Utils.swift b/RespectU/Sources/Utils/Utils.swift index 80c5bfa..885deab 100644 --- a/RespectU/Sources/Utils/Utils.swift +++ b/RespectU/Sources/Utils/Utils.swift @@ -66,7 +66,7 @@ final class Utils { case .button8: songButtonInfo = songInfo.button8 default: - break + songButtonInfo = nil } guard let bindedSongButtonInfo = songButtonInfo else { return 0 } guard let highestSkillPoint = [ @@ -247,7 +247,8 @@ final class Utils { recordButtonInfo = recordInfo.button8 songButtonInfo = songInfo.button8 default: - break + recordButtonInfo = nil + songButtonInfo = nil } if songButtonInfo?.normal != 0 { entire += 1 diff --git a/RespectU/Sources/ViewControllers/BaseViewController.swift b/RespectU/Sources/ViewControllers/BaseViewController.swift index dcb6d49..86f82c8 100644 --- a/RespectU/Sources/ViewControllers/BaseViewController.swift +++ b/RespectU/Sources/ViewControllers/BaseViewController.swift @@ -13,11 +13,6 @@ import XLPagerTabStrip /// The base view controller to use button bar pager tap strip. class BaseViewController: ButtonBarPagerTabStripViewController { - private enum Font { - - static let buttonBarItem = UIFont.systemFont(ofSize: 14, weight: .medium) - } - override func viewDidLoad() { setUpButtonBarPagerTabStrip() super.viewDidLoad() @@ -30,6 +25,6 @@ class BaseViewController: ButtonBarPagerTabStripViewController { settings.style.buttonBarItemBackgroundColor = .white settings.style.buttonBarItemTitleColor = .black settings.style.buttonBarItemsShouldFillAvailiableWidth = true - settings.style.buttonBarItemFont = Font.buttonBarItem + settings.style.buttonBarItemFont = UIFont.systemFont(ofSize: 14, weight: .medium) } } diff --git a/RespectU/Sources/ViewControllers/DownloadViewController.swift b/RespectU/Sources/ViewControllers/DownloadViewController.swift index 5f161b6..41ae5ca 100644 --- a/RespectU/Sources/ViewControllers/DownloadViewController.swift +++ b/RespectU/Sources/ViewControllers/DownloadViewController.swift @@ -17,21 +17,22 @@ final class DownloadViewController: UIViewController { // MARK: Property. /// The api service. - let apiService: APIServiceType = APIService() + private let apiService: APIServiceType = APIService() /// The 'download data' label. - @IBOutlet weak var downloadDataLabel: UILabel! + @IBOutlet private weak var downloadDataLabel: UILabel! /// The 'download data' button. - @IBOutlet weak var downloadDataButton: UIButton! + @IBOutlet private weak var downloadDataButton: UIButton! /// The 'download record' label. - @IBOutlet weak var downloadRecordLabel: UILabel! + @IBOutlet private weak var downloadRecordLabel: UILabel! /// The 'download record' button. - @IBOutlet weak var downloadRecordButton: UIButton! + @IBOutlet private weak var downloadRecordButton: UIButton! - var isVersionValid: Bool = false { + /// The boolean value indicating whether the requested version is valid to request data. + private var isVersionValid: Bool = false { didSet { if isVersionValid { SVProgressHUD.show() @@ -45,25 +46,33 @@ final class DownloadViewController: UIViewController { } } - var isSongRequestFinished: Bool = false + /// The boolean value indicating wheter the request about song is finished. + private var isSongRequestFinished: Bool = false - var isMissionRequestFinished: Bool = false + /// The boolean value indicating wheter the request about mission is finished. + private var isMissionRequestFinished: Bool = false - var isTrophyRequestFinished: Bool = false + /// The boolean value indicating wheter the request about trophy is finished. + private var isTrophyRequestFinished: Bool = false - var isAchievementRequestFinished: Bool = false + /// The boolean value indicating wheter the request about achievement is finished. + private var isAchievementRequestFinished: Bool = false - var isTipRequestFinished: Bool = false + /// The boolean value indicating wheter the request about tip is finished. + private var isTipRequestFinished: Bool = false - var isVersionRequestFinished: Bool = false + /// The boolean value indicating wheter the request about version is finished. + private var isVersionRequestFinished: Bool = false - var isRecordRequestFinished: Bool = false + /// The boolean value indicating wheter the request about record is finished. + private var isRecordRequestFinished: Bool = false - var numberOfRequests = 0 { + /// The number of requests. + private var numberOfRequests = 0 { didSet { if numberOfRequests == 6 { SVProgressHUD.dismiss() - if finishesDataAll { + if isAllRequestFinished { presentSuccessAlert() } else { presentFailureAlert() @@ -73,7 +82,8 @@ final class DownloadViewController: UIViewController { } } - var numberOfRecordRequests = 0 { + /// The number of requests about record. + private var numberOfRecordRequests = 0 { didSet { if numberOfRecordRequests == 1 { SVProgressHUD.dismiss() @@ -87,7 +97,8 @@ final class DownloadViewController: UIViewController { } } - var finishesDataAll: Bool { + /// The boolean value indicating wheter all the requests are finished. + private var isAllRequestFinished: Bool { if isSongRequestFinished, isMissionRequestFinished, isTrophyRequestFinished, @@ -104,6 +115,7 @@ final class DownloadViewController: UIViewController { configure() } + /// Configures initial settings. private func configure() { downloadDataLabel.text = L10n.updateWithLatestData downloadRecordLabel.text = L10n.getExportedPerformanceRecordData @@ -116,7 +128,7 @@ final class DownloadViewController: UIViewController { } @objc func downloadDataButtonDidTap(_ sender: UIButton) { - apiService.requestVersions(completion: versionCheckHandler(response:error:)) + apiService.requestVersions(completion: versionCheckHandler) } @objc func downloadRecordButtonDidTap(_ sender: UIButton) { @@ -148,6 +160,8 @@ final class DownloadViewController: UIViewController { } } +// MARK: - Request Handler + private extension DownloadViewController { func songRequestHandler(response: SongResponse?, error: Error?) { @@ -208,7 +222,7 @@ private extension DownloadViewController { RecordInfo.add(recordInfo) } } - Skill.refresh() + Utils.refreshSkillPoints() isSongRequestFinished = true plusDataCount() } @@ -372,6 +386,8 @@ private extension DownloadViewController { } } +// MARK: - Private Method + private extension DownloadViewController { func presentSuccessAlert() { diff --git a/RespectU/Sources/ViewControllers/Mission/MissionBaseTableViewController.swift b/RespectU/Sources/ViewControllers/Mission/MissionBaseTableViewController.swift index 3468c79..dce329b 100644 --- a/RespectU/Sources/ViewControllers/Mission/MissionBaseTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Mission/MissionBaseTableViewController.swift @@ -62,7 +62,8 @@ extension MissionBaseTableViewController { return (results?.count ?? 0) / 6 } - override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + override func tableView(_ tableView: UITableView, + titleForHeaderInSection section: Int) -> String? { return results?[section * 6].section } diff --git a/RespectU/Sources/ViewControllers/PerformanceViewController.swift b/RespectU/Sources/ViewControllers/PerformanceViewController.swift index 6ed9fc7..b86c35a 100644 --- a/RespectU/Sources/ViewControllers/PerformanceViewController.swift +++ b/RespectU/Sources/ViewControllers/PerformanceViewController.swift @@ -12,37 +12,42 @@ import RealmSwift import StoreKit import SwiftKeychainWrapper +/// The performance view controller. final class PerformanceViewController: UIViewController { + /// The `enum` that defines cell identifiers. private enum CellIdentifier { + /// The `SkillLevelCell` identifier. + static let skillLevel = "skillLevelCell" + /// The `SummaryCell` cell identifier. + static let summary = "summaryCell" + + /// The `SummaryCollectionCell` cell identifier. + static let summaryCollection = "summaryCollectionCell" } + /// The api service. private let apiService: APIServiceType = APIService() + /// The table view. @IBOutlet private weak var tableView: UITableView! + /// The record button. @IBOutlet private weak var recordButton: UIButton! + /// The nickname button. @IBOutlet private weak var nicknameButton: UIButton! - var favoriteButton = UserDefaults.standard.string(forKey: "favoriteButton") ?? Button.button4 - override func viewDidLoad() { super.viewDidLoad() - recordButton.layer.cornerRadius = recordButton.bounds.height / 2 - recordButton.layer.borderWidth = 1 - recordButton.layer.borderColor = UIColor.main.cgColor - tableView.register(UINib(nibName: "SkillLevelCell", bundle: nil), forCellReuseIdentifier: "skillLevelCell") - tableView.register(UINib(nibName: "SummaryCell", bundle: nil), forCellReuseIdentifier: "summaryCell") - self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false - APIService.requestVersions(completion: didReceiveVersions) + setup() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(true) - setup() + resetSubviews() } override func viewDidAppear(_ animated: Bool) { @@ -51,9 +56,20 @@ final class PerformanceViewController: UIViewController { } private func setup() { + recordButton.layer.cornerRadius = recordButton.bounds.height / 2 + recordButton.layer.borderWidth = 1 + recordButton.layer.borderColor = UIColor.main.cgColor + tableView.register(UINib(nibName: SkillLevelCell.name, bundle: nil), + forCellReuseIdentifier: CellIdentifier.skillLevel) + tableView.register(UINib(nibName: SummaryCell.name, bundle: nil), + forCellReuseIdentifier: CellIdentifier.summary) + navigationController?.interactivePopGestureRecognizer?.isEnabled = false + apiService.requestVersions(completion: versionRequestHandler) + } + + private func resetSubviews() { recordButton.setTitle(L10n.performanceRecord, for: .normal) - favoriteButton = UserDefaults.standard.string(forKey: "favoriteButton") ?? Button.button4 - nicknameButton.setTitle(UserDefaults.standard.string(forKey: "nickname") ?? L10n.nicknameSetting, for: []) + nicknameButton.setTitle(Persistence.nickname, for: []) tableView.reloadData() } @@ -66,20 +82,20 @@ final class PerformanceViewController: UIViewController { .present(to: self) return } - let alert = UIAlertController.alert(title: L10n.nicknameSetting, message: L10n.enterYourNickname) - alert.textField { textField in - textField.placeholder = L10n.nickname - } + let alert = UIAlertController + .alert(title: L10n.nicknameSetting, message: L10n.enterYourNickname) + alert + .textField { $0.placeholder = L10n.nickname } .action(title: L10n.ok) { [weak self] _ in + guard let self = self else { return } if let input = alert.textFields?.first?.text { if !input.isEmpty { - apiservice.uploadNickname(id: id, nickname: input, completion: self?.didReceiveUploadNickname) + self.apiService.uploadNickname(id: id, + nickname: input, + completion: self.nicknameUploadRequestHandler) let nickname = input.trimmingCharacters(in: .whitespaces) - UserDefaults.standard.do { - $0.set(nickname, forKey: "nickname") - $0.synchronize() - } - self?.nicknameButton.setTitle(nickname, for: .normal) + Persistence.nickname = nickname + self.nicknameButton.setTitle(nickname, for: .normal) } } } @@ -98,11 +114,11 @@ final class PerformanceViewController: UIViewController { } } -// MARK: - Version +// MARK: - Request Handler private extension PerformanceViewController { - func didReceiveVersions(response: VersionResponse?, error: Error?) { + func versionRequestHandler(response: VersionResponse?, error: Error?) { if let error = error { present(UIAlertController.makeErrorAlert(error), animated: true, completion: nil) return @@ -112,16 +128,13 @@ private extension PerformanceViewController { if version != response.clientVersion { DispatchQueue.main.async { UIAlertController - .alert(title: "", message: "New version released!\nPlease use it after updating.".localized) + .alert(title: "", message: L10n.newVersionReleasedPleaseUseItAfterUpdating) .action(title: L10n.update) { _ in - guard let url = URL(string: "itms-apps://itunes.apple.com/app/id1291664067") else { return } - guard #available(iOS 10, *) else { - UIApplication.shared.openURL(url) - return - } + guard let url + = URL(string: "itms-apps://itunes.apple.com/app/id1291664067") else { return } UIApplication.shared.open(url, options: [:]) } - .action(title: "Cancel".localized, style: .cancel) + .action(title: L10n.cancel, style: .cancel) .present(to: self) } } else if response.serverVersion != versionInfo.serverVersion { @@ -139,13 +152,8 @@ private extension PerformanceViewController { } } } -} - -// MARK: - Nickname - -private extension PerformanceViewController { - func didReceiveUploadNickname(statusCode: Int?, error: Error?) { + func nicknameUploadRequestHandler(statusCode: Int?, error: Error?) { if let error = error { present(UIAlertController.makeErrorAlert(error), animated: true, completion: nil) return @@ -176,20 +184,29 @@ extension PerformanceViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { switch indexPath.section { case 0: - guard let cell = tableView.dequeueReusableCell(withIdentifier: "skillLevelCell", for: indexPath) as? SkillLevelCell else { return UITableViewCell() } - cell.delegate = self - cell.selectionStyle = .none - cell.setProperties(favoriteButton, max: Skill.maxSkillPoint(button: favoriteButton), myRecord: Skill.mySkillPointAndHighestSeries(button: favoriteButton)) + let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.skillLevel, + for: indexPath) + if case let skillLevelCell as SkillLevelCell = cell { + let favoriteButton = Persistence.favoriteButton + skillLevelCell.delegate = self + skillLevelCell.selectionStyle = .none + skillLevelCell.configure(inButton: favoriteButton, + max: Utils.maxSkillPoint(in: favoriteButton), + record: Utils.totalSkillPointAndHighestSeries(in: favoriteButton)) + } return cell case 1: - guard let cell = tableView.dequeueReusableCell(withIdentifier: "summaryCell", for: indexPath) as? SummaryCell else { return UITableViewCell() } - cell.delegate = self - cell.selectionStyle = .none - cell.collectionView.dataSource = self - cell.collectionView.register(UINib(nibName: "SummaryCollectionCell", bundle: nil), forCellWithReuseIdentifier: "summaryCollectionCell") - return cell - default: - return UITableViewCell() + let cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier.summary, + for: indexPath) + if case let summaryCell as SummaryCell = cell { + summaryCell.delegate = self + summaryCell.selectionStyle = .none + summaryCell.collectionView.dataSource = self + summaryCell.collectionView + .register(UINib(nibName: SummaryCollectionCell.name, bundle: nil), + forCellWithReuseIdentifier: CellIdentifier.summaryCollection) + } default: + return UITableViewCell() } } @@ -227,16 +244,18 @@ extension PerformanceViewController: UITableViewDelegate { extension PerformanceViewController: UICollectionViewDataSource { - func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + func collectionView(_ collectionView: UICollectionView, + cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView - .dequeueReusableCell(withReuseIdentifier: "summaryCollectionCell", for: indexPath) + .dequeueReusableCell(withReuseIdentifier: CellIdentifier.summaryCollection, for: indexPath) if case let summaryCollectionCell as SummaryCollectionCell = cell { summaryCollectionCell.setProperties(RecordInfo.fetch(), at: indexPath.item) } return cell } - func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + func collectionView(_ collectionView: UICollectionView, + numberOfItemsInSection section: Int) -> Int { return 7 } } @@ -260,26 +279,25 @@ extension PerformanceViewController: SkillLevelCellDelegate { extension PerformanceViewController: SummaryCellDelegate { - func didTouchUpDetailButton(_ sender: UIButton) { - let controller = StoryboardScene.Performance.summaryDetailViewController.instantiate() + func summaryCell(_ cell: SummaryCell, didTapSearchButton button: UIButton) { + let controller = StoryboardScene.Performance.searchRecordViewController.instantiate() present(controller, animated: true) } - func didTouchUpSearchButton(_ sender: UIButton) { - let controller = StoryboardScene.Performance.searchRecordViewController.instantiate() + func summaryCell(_ cell: SummaryCell, didTapDetailButton button: UIButton) { + let controller = StoryboardScene.Performance.summaryDetailViewController.instantiate() present(controller, animated: true) } } -extension PerformanceViewController { +// MARK: - Private Method + +private extension PerformanceViewController { - private func presentRateView() { - if #available(iOS 10.3, *) { - let appOpenCount = UserDefaults.standard.integer(forKey: "appOpenCount") - UserDefaults.standard.set(appOpenCount + 1, forKey: "appOpenCount") - if UserDefaults.standard.integer(forKey: "appOpenCount") % 10 == 0 { - SKStoreReviewController.requestReview() - } + func presentRateView() { + Persistence.numberOfLaunching += 1 + if Persistence.numberOfLaunching % 10 == 0 { + SKStoreReviewController.requestReview() } } } diff --git a/RespectU/Sources/ViewControllers/Record/RecordBaseTableViewController.swift b/RespectU/Sources/ViewControllers/Record/RecordBaseTableViewController.swift index 48bebb9..87f907a 100644 --- a/RespectU/Sources/ViewControllers/Record/RecordBaseTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Record/RecordBaseTableViewController.swift @@ -10,33 +10,27 @@ import UIKit import RealmSwift +/// The record base table view controller. class RecordBaseTableViewController: UITableViewController { - var recordViewController: RecordViewController { - guard let parent = self.parent as? RecordViewController else { return RecordViewController() } + private var recordViewController: RecordViewController { + guard let parent = parent as? RecordViewController else { return RecordViewController() } return parent } - let favoriteButton = UserDefaults.standard.string(forKey: "favoriteButton") ?? "4b" - var tempSongResults: Results? var songResults: [SongInfo]? - var recordResults: Results? + private var recordResults: Results? - var recordView: RecordView! + private var recordView: RecordView! - let cellIdentifier = "recordCell" + private let cellIdentifier = "recordCell" override func viewDidLoad() { super.viewDidLoad() - tempSongResults = SongInfo.fetch() - recordResults = RecordInfo.fetch() - tableView.showsVerticalScrollIndicator = false - tableView.separatorStyle = .none - tableView.register(UINib(nibName: "RecordCell", bundle: nil), - forCellReuseIdentifier: cellIdentifier) + configure() } override func viewWillDisappear(_ animated: Bool) { @@ -48,6 +42,15 @@ class RecordBaseTableViewController: UITableViewController { super.viewDidAppear(animated) dismissRecordViewIfExists() } + + private func configure() { + tempSongResults = SongInfo.fetch() + recordResults = RecordInfo.fetch() + tableView.showsVerticalScrollIndicator = false + tableView.separatorStyle = .none + tableView.register(UINib(nibName: RecordCell.name, bundle: nil), + forCellReuseIdentifier: cellIdentifier) + } } extension RecordBaseTableViewController { @@ -57,7 +60,7 @@ extension RecordBaseTableViewController { let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) guard case let recordCell as RecordCell = cell else { return UITableViewCell() } guard let object = songResults?[indexPath.row] else { return UITableViewCell() } - recordCell.configure(object) + recordCell.configure(with: object) if let selectedIndexPath = tableView.indexPathForSelectedRow { if selectedIndexPath == indexPath { recordCell.setColorsInSong(object.series, labels: recordCell.labels) @@ -80,11 +83,11 @@ extension RecordBaseTableViewController { let predicate = NSPredicate(format: "%K == %@", #keyPath(RecordInfo.title.english), songResult.title?.english ?? "") - guard let object = self.recordResults?.filter(predicate).first else { return } + guard let object = recordResults?.filter(predicate).first else { return } cell.setColorsInSong(object.series, labels: cell.labels) - self.recordView = UIView.instantiateFromXib(xibName: "RecordView") as? RecordView - self.recordView.delegate = self - self.recordView.translatesAutoresizingMaskIntoConstraints = false + recordView = UIView.instantiateFromXib(xibName: RecordView.name) as? RecordView + recordView.delegate = self + recordView.translatesAutoresizingMaskIntoConstraints = false recordViewController.view.addSubview(recordView) let leadingConstraint = recordView.leadingAnchor .constraint(equalTo: recordViewController.view.leadingAnchor, constant: 8) @@ -94,15 +97,9 @@ extension RecordBaseTableViewController { .constraint(equalToConstant: 200) let centerXConstraint = recordView.centerXAnchor .constraint(equalTo: recordViewController.view.centerXAnchor) - let bottomConstraint: NSLayoutConstraint - if #available(iOS 11.0, *) { - bottomConstraint = recordView.safeAreaLayoutGuide.bottomAnchor - .constraint(equalTo: recordViewController.view.safeAreaLayoutGuide.bottomAnchor, - constant: -20) - } else { - bottomConstraint = recordView.bottomAnchor - .constraint(equalTo: recordViewController.view.bottomAnchor, constant: -20) - } + let bottomConstraint = recordView.safeAreaLayoutGuide.bottomAnchor + .constraint(equalTo: recordViewController.view.safeAreaLayoutGuide.bottomAnchor, + constant: -20) NSLayoutConstraint.activate([ leadingConstraint, trailingConstraint, @@ -110,8 +107,8 @@ extension RecordBaseTableViewController { centerXConstraint, bottomConstraint ]) - self.recordView.updateRankingAndSkillPointLabel(object, button: favoriteButton) - self.recordView.reloadButtonsAndLabels(object, button: favoriteButton) + recordView.updateRankingAndSkillPointLabel(with: object, inButton: Persistence.favoriteButton) + recordView.reloadButtonsAndLabels(with: object, inButton: Persistence.favoriteButton) recordViewController.scrollViewBottomConstraint.constant += 210 recordViewController.view.layoutIfNeeded() tableView.scrollToNearestSelectedRow(at: .middle, animated: true) @@ -124,7 +121,7 @@ extension RecordBaseTableViewController { override func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) { guard let cell = tableView.cellForRow(at: indexPath) as? RecordCell else { return } - guard let object = self.songResults?[indexPath.row] else { return } + guard let object = songResults?[indexPath.row] else { return } cell.setColorsInSong(object.series, labels: cell.labels) } @@ -206,10 +203,10 @@ extension RecordBaseTableViewController: RecordViewDelegate { Enter the rate.\nTo reset the value, do not enter any values. """ let alert = UIAlertController - .alert(title: L10n.rate, message: message.localized) - alert.textField { (textField) in - textField.keyboardType = .decimalPad - textField.placeholder = L10n.rate + .alert(title: L10n.rating, message: message.localized) + alert.textField { + $0.keyboardType = .decimalPad + $0.placeholder = L10n.rating } .action(title: L10n.ok) { [weak self] _ in let input = alert.textFields?.first?.text ?? "" @@ -317,6 +314,7 @@ private extension RecordBaseTableViewController { guard let songButtonKeyPath = songResult.value(forKeyPath: button.expansion ?? "") as? SongButtonInfo else { return } + let buttonExpansion = button.expansion ?? "" let normalSkillPoint = Utils .skillPoint(difficulty: songButtonKeyPath.normal, rate: recordButtonKeyPath.normal?.rate, @@ -331,25 +329,25 @@ private extension RecordBaseTableViewController { note: Note(rawValue: recordButtonKeyPath.maximum?.note ?? "") ?? .none) guard let skillPoint = [normalSkillPoint, hardSkillPoint, maximumSkillPoint].sorted().last else { return } - RecordInfo.update(recordInfo, with: ["\(button.expansion ?? "").skillPoint": skillPoint]) + RecordInfo.update(recordInfo, with: ["\(buttonExpansion).skillPoint": skillPoint]) switch skillPoint { case normalSkillPoint: RecordInfo.update(recordInfo, with: [ - "\(button.expansion ?? "").skillPointDifficulty": Difficulty.normal.rawValue, - "\(button.expansion ?? "").skillPointRate": recordButtonKeyPath.normal?.rate ?? 0, - "\(button.expansion ?? "").skillPointNote": recordButtonKeyPath.normal?.note ?? "" + "\(buttonExpansion).skillPointDifficulty": Difficulty.normal.rawValue, + "\(buttonExpansion).skillPointRate": recordButtonKeyPath.normal?.rate ?? 0, + "\(buttonExpansion).skillPointNote": recordButtonKeyPath.normal?.note ?? "" ]) case hardSkillPoint: RecordInfo.update(recordInfo, with: [ - "\(button.expansion ?? "").skillPointDifficulty": Difficulty.hard.rawValue, - "\(button.expansion ?? "").skillPointRate": recordButtonKeyPath.hard?.rate ?? 0, - "\(button.expansion ?? "").skillPointNote": recordButtonKeyPath.hard?.note ?? "" + "\(buttonExpansion).skillPointDifficulty": Difficulty.hard.rawValue, + "\(buttonExpansion).skillPointRate": recordButtonKeyPath.hard?.rate ?? 0, + "\(buttonExpansion).skillPointNote": recordButtonKeyPath.hard?.note ?? "" ]) case maximumSkillPoint: RecordInfo.update(recordInfo, with: [ - "\(button.expansion ?? "").skillPointDifficulty": Difficulty.maximum.rawValue, - "\(button.expansion ?? "").skillPointRate": recordButtonKeyPath.maximum?.rate ?? 0, - "\(button.expansion ?? "").skillPointNote": recordButtonKeyPath.maximum?.note ?? "" + "\(buttonExpansion).skillPointDifficulty": Difficulty.maximum.rawValue, + "\(buttonExpansion).skillPointRate": recordButtonKeyPath.maximum?.rate ?? 0, + "\(buttonExpansion).skillPointNote": recordButtonKeyPath.maximum?.note ?? "" ]) default: break @@ -357,9 +355,8 @@ private extension RecordBaseTableViewController { } func dismissRecordViewIfExists() { - let lastSubview = recordViewController.view.subviews.last - if lastSubview is RecordView { - lastSubview?.removeFromSuperview() + if let lastSubview = recordViewController.view.subviews.last as? RecordView { + lastSubview.removeFromSuperview() recordViewController.scrollViewBottomConstraint.constant -= 210 } } diff --git a/RespectU/Sources/ViewControllers/SearchRecordViewController.swift b/RespectU/Sources/ViewControllers/SearchRecordViewController.swift index 5ef9ab2..be65398 100644 --- a/RespectU/Sources/ViewControllers/SearchRecordViewController.swift +++ b/RespectU/Sources/ViewControllers/SearchRecordViewController.swift @@ -50,7 +50,7 @@ final class SearchRecordViewController: UIViewController { private func configure() { searchByLevelButton.setTitle(L10n.level, for: []) - searchByRateButton.setTitle(L10n.rate, for: []) + searchByRateButton.setTitle(L10n.rating, for: []) searchByNoteButton.setTitle(L10n.note, for: []) searchButton.setTitle(L10n.enterAllConditions, for: .disabled) searchButton.setTitle(L10n.search, for: .normal) @@ -273,8 +273,8 @@ extension SearchRecordViewController: SearchByRatingViewDelegate { extension SearchRecordViewController: SearchByNoteViewDelegate { - func didTouchUpNoteButtons(_ sender: UIButton) { - switch sender.tag { + func searchByNoteView(_ view: SearchByNoteView, didTapNoteButton button: UIButton) { + switch button.tag { case 0: selectedNoteDetailIndex = 0 case 1: diff --git a/RespectU/Sources/ViewControllers/Song/SongBaseTableViewController.swift b/RespectU/Sources/ViewControllers/Song/SongBaseTableViewController.swift index c4e9799..9aa0638 100644 --- a/RespectU/Sources/ViewControllers/Song/SongBaseTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Song/SongBaseTableViewController.swift @@ -39,7 +39,7 @@ class SongBaseTableViewController: UITableViewController { #keyPath(MissionInfo.reward.english), "Music*") missionResults = MissionInfo.fetch().filter(predicate) - achievementResults = AchievementInfo.fetch(byType: .all).filter("type = music") + achievementResults = AchievementInfo.fetch(byType: .music) tableView.rowHeight = 60 tableView.showsVerticalScrollIndicator = false tableView.separatorStyle = .none @@ -100,7 +100,7 @@ extension SongBaseTableViewController { } var message: String = L10n.speedRecommendation + "\n\(speed)" + unlockInfo if changesSpeed { - message += "\n" + L10n.speedVariation + message += "\n\(L10n.speedVariation)" } UIAlertController .alert(title: object.localizedTitle, message: message) @@ -117,6 +117,6 @@ extension SongBaseTableViewController { override func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) { guard let cell = tableView.cellForRow(at: indexPath) as? SongCell else { return } - cell.unsetColors(labels: cell.labels) + cell.decolorizeSubviews() } } diff --git a/RespectU/Sources/ViewControllers/Top50/Top504BTableViewController.swift b/RespectU/Sources/ViewControllers/Top50/Top504BTableViewController.swift index a3bc93b..cac1411 100644 --- a/RespectU/Sources/ViewControllers/Top50/Top504BTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Top50/Top504BTableViewController.swift @@ -25,7 +25,6 @@ final class Top504BTableViewController: Top50BaseTableViewController { top50Cell.configure(with: object, button: .button8) } return cell - } } diff --git a/RespectU/Sources/ViewControllers/Top50/Top506BTableViewController.swift b/RespectU/Sources/ViewControllers/Top50/Top506BTableViewController.swift index 22bbeb2..cff694c 100644 --- a/RespectU/Sources/ViewControllers/Top50/Top506BTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Top50/Top506BTableViewController.swift @@ -25,7 +25,6 @@ final class Top506BTableViewController: Top50BaseTableViewController { top50Cell.configure(with: object, button: .button8) } return cell - } } diff --git a/RespectU/Sources/ViewControllers/Top50/Top50BaseTableViewController.swift b/RespectU/Sources/ViewControllers/Top50/Top50BaseTableViewController.swift index 7b5f369..d3f72f4 100644 --- a/RespectU/Sources/ViewControllers/Top50/Top50BaseTableViewController.swift +++ b/RespectU/Sources/ViewControllers/Top50/Top50BaseTableViewController.swift @@ -23,7 +23,8 @@ class Top50BaseTableViewController: UITableViewController { tableView.showsVerticalScrollIndicator = false tableView.separatorStyle = .none tableView.rowHeight = 60 - tableView.register(UINib(nibName: "Top50Cell", bundle: nil), forCellReuseIdentifier: cellIdentifier) + tableView.register(UINib(nibName: Top50Cell.name, bundle: nil), + forCellReuseIdentifier: cellIdentifier) } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { diff --git a/RespectU/Sources/Views/RecordCell.swift b/RespectU/Sources/Views/RecordCell.swift index 225cf3c..5400d37 100644 --- a/RespectU/Sources/Views/RecordCell.swift +++ b/RespectU/Sources/Views/RecordCell.swift @@ -35,4 +35,12 @@ final class RecordCell: UITableViewCell { colorLabel.layer.addSublayer(gradient) titleLabel.text = songInfo.localizedTitle } + + func colorizeSubviews(in series: Series) { + + } + + func decolorizeSubviews() { + + } } diff --git a/RespectU/Sources/Views/SongCell.swift b/RespectU/Sources/Views/SongCell.swift index a11fd6c..a5e9f37 100644 --- a/RespectU/Sources/Views/SongCell.swift +++ b/RespectU/Sources/Views/SongCell.swift @@ -82,15 +82,12 @@ final class SongCell: UITableViewCell { case .button8: buttonInfo = songInfo.button8 default: - break + buttonInfo = nil } normalLabel.text = buttonInfo?.normal == 0 ? "-" : "\(buttonInfo?.normal ?? 0)" hardLabel.text = buttonInfo?.hard == 0 ? "-" : "\(buttonInfo?.hard ?? 0)" maximumLabel.text = buttonInfo?.maximum == 0 ? "-" : "\(buttonInfo?.maximum ?? 0)" } -} - -extension SongCell { /// Colorizes subviews. /// @@ -130,4 +127,15 @@ extension SongCell { } } } + + /// Decolorizes subviews. + /// + /// Reset all the colors of subviews. + func decolorizeSubviews() { + DispatchQueue.main.async { [weak self] in + self?.contentView.backgroundColor = .white + self?.allLabel.forEach { $0.textColor = .black } + } + } + } diff --git a/RespectU/Sources/Views/SummaryCell.swift b/RespectU/Sources/Views/SummaryCell.swift index 2c32b81..b4d46ca 100644 --- a/RespectU/Sources/Views/SummaryCell.swift +++ b/RespectU/Sources/Views/SummaryCell.swift @@ -7,49 +7,59 @@ // import UIKit + import RealmSwift protocol SummaryCellDelegate: class { - func didTouchUpDetailButton(_ sender: UIButton) - func didTouchUpSearchButton(_ sender: UIButton) + + func summaryCell(_ cell: SummaryCell, didTapSearchButton button: UIButton) + + func summaryCell(_ cell: SummaryCell, didTapDetailButton button: UIButton) } +/// The summary table view cell. final class SummaryCell: UITableViewCell { weak var delegate: SummaryCellDelegate? - @IBOutlet weak var titleLabel: UILabel! + /// The title label. + @IBOutlet private weak var titleLabel: UILabel! - @IBOutlet weak var view: UIView! + /// The background view. + @IBOutlet private weak var view: UIView! - @IBOutlet weak var collectionView: UICollectionView! + /// The collection view. + @IBOutlet private weak var collectionView: UICollectionView! - @IBOutlet weak var detailButton: UIButton! + /// The detail button. + @IBOutlet private weak var detailButton: UIButton! - @IBOutlet weak var searchButton: UIButton! + /// The search button. + @IBOutlet private weak var searchButton: UIButton! override func awakeFromNib() { super.awakeFromNib() - titleLabel.text = "Summary".localized + setup() + } + + /// Configures initial settings. + private func setup() { + titleLabel.text = L10n.summary view.layer.cornerRadius = 15 view.layer.borderWidth = 1 view.layer.borderColor = UIColor.lightGray.cgColor view.layer.masksToBounds = true - self.detailButton.setTitle("Detail".localized, for: .normal) - self.searchButton.setTitle("Search by Condition".localized, for: .normal) - self.detailButton.addTarget(self, action: #selector(didTouchUpDetailButton(_:)), for: .touchUpInside) - self.searchButton.addTarget(self, action: #selector(searchButtonDidTap(_:)), for: .touchUpInside) - } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) + detailButton.setTitle(L10n.detail, for: .normal) + searchButton.setTitle(L10n.searchByCondition, for: .normal) + detailButton.addTarget(self, action: #selector(detailButtonDidTap(_:)), for: .touchUpInside) + searchButton.addTarget(self, action: #selector(searchButtonDidTap(_:)), for: .touchUpInside) } - @objc func didTouchUpSearchButton(_ sender: UIButton) { - delegate?.didTouchUpSearchButton(sender) + @objc private func searchButtonDidTap(_ sender: UIButton) { + delegate?.summaryCell(self, didTapSearchButton: sender) } - @objc func didTouchUpDetailButton(_ sender: UIButton) { - delegate?.didTouchUpDetailButton(sender) + @objc private func detailButtonDidTap(_ sender: UIButton) { + delegate?.summaryCell(self, didTapDetailButton: sender) } }