diff --git a/AppShared/Info.plist b/AppShared/Info.plist index 222a7a1db..1958eb540 100644 --- a/AppShared/Info.plist +++ b/AppShared/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 diff --git a/CoreDataStack/Info.plist b/CoreDataStack/Info.plist index 222a7a1db..1958eb540 100644 --- a/CoreDataStack/Info.plist +++ b/CoreDataStack/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 diff --git a/CoreDataStackTests/Info.plist b/CoreDataStackTests/Info.plist index 222a7a1db..1958eb540 100644 --- a/CoreDataStackTests/Info.plist +++ b/CoreDataStackTests/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 4337bdc7d..600d1f4bb 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -347,6 +347,8 @@ DB6D9F9726367249008423CD /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6D9F9626367249008423CD /* SettingsViewController.swift */; }; DB6F5E35264E78E7009108F4 /* AutoCompleteViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6F5E34264E78E7009108F4 /* AutoCompleteViewController.swift */; }; DB6F5E38264E994A009108F4 /* AutoCompleteTopChevronView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6F5E37264E994A009108F4 /* AutoCompleteTopChevronView.swift */; }; + DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71C7CA271D5A0300BE3819 /* LineChartView.swift */; }; + DB71C7CD271D7F4300BE3819 /* CurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71C7CC271D7F4300BE3819 /* CurveAlgorithm.swift */; }; DB71FD2C25F86A5100512AE1 /* AvatarStackContainerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD2B25F86A5100512AE1 /* AvatarStackContainerButton.swift */; }; DB71FD3625F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD3525F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift */; }; DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD3B25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift */; }; @@ -1141,6 +1143,8 @@ DB6D9F9626367249008423CD /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; DB6F5E34264E78E7009108F4 /* AutoCompleteViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCompleteViewController.swift; sourceTree = ""; }; DB6F5E37264E994A009108F4 /* AutoCompleteTopChevronView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCompleteTopChevronView.swift; sourceTree = ""; }; + DB71C7CA271D5A0300BE3819 /* LineChartView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineChartView.swift; sourceTree = ""; }; + DB71C7CC271D7F4300BE3819 /* CurveAlgorithm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurveAlgorithm.swift; sourceTree = ""; }; DB71FD2B25F86A5100512AE1 /* AvatarStackContainerButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarStackContainerButton.swift; sourceTree = ""; }; DB71FD3525F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+PersistMemo.swift"; sourceTree = ""; }; DB71FD3B25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+PersistCache.swift"; sourceTree = ""; }; @@ -1750,6 +1754,7 @@ 2D5A3D0125CF8640002347D6 /* Vender */ = { isa = PBXGroup; children = ( + DB71C7CC271D7F4300BE3819 /* CurveAlgorithm.swift */, 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */, DB51D170262832380062B7A1 /* BlurHashDecode.swift */, DB51D171262832380062B7A1 /* BlurHashEncode.swift */, @@ -1954,6 +1959,7 @@ isa = PBXGroup; children = ( 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */, + DB71C7CA271D5A0300BE3819 /* LineChartView.swift */, ); path = View; sourceTree = ""; @@ -4162,6 +4168,7 @@ DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */, DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */, 2D34D9CB261489930081BFC0 /* SearchViewController+Recommend.swift in Sources */, + DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */, DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */, DB482A45261335BA008AE74C /* UserTimelineViewController+Provider.swift in Sources */, 2D206B8625F5FB0900143C56 /* Double.swift in Sources */, @@ -4230,6 +4237,7 @@ DB8AF52E25C13561002E6C99 /* ViewStateStore.swift in Sources */, DB1D61CF26F1B33600DA8662 /* WelcomeViewModel.swift in Sources */, 2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */, + DB71C7CD271D7F4300BE3819 /* CurveAlgorithm.swift in Sources */, DBD376B2269302A4007FEC24 /* UITableViewCell.swift in Sources */, DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */, DBAC6499267DF2C4007FE9FD /* TimelineBottomLoaderNode.swift in Sources */, @@ -4784,7 +4792,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4813,7 +4821,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4921,11 +4929,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4952,11 +4960,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4981,11 +4989,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = CoreDataStack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5011,11 +5019,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = CoreDataStack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5078,7 +5086,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5103,7 +5111,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5128,7 +5136,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5153,7 +5161,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5178,7 +5186,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5203,7 +5211,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5228,7 +5236,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5253,7 +5261,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5344,7 +5352,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -5411,11 +5419,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = CoreDataStack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5460,7 +5468,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5485,11 +5493,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5581,7 +5589,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -5648,11 +5656,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = CoreDataStack/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5697,7 +5705,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5722,11 +5730,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 74; + DYLIB_CURRENT_VERSION = 78; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5752,7 +5760,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5776,7 +5784,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 74; + CURRENT_PROJECT_VERSION = 78; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index beafe8c8e..424b6b090 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -7,12 +7,12 @@ AppShared.xcscheme_^#shared#^_ orderHint - 43 + 44 CoreDataStack.xcscheme_^#shared#^_ orderHint - 44 + 43 Mastodon - ASDK.xcscheme_^#shared#^_ @@ -37,7 +37,7 @@ Mastodon - ca.xcscheme_^#shared#^_ orderHint - 18 + 16 Mastodon - de.xcscheme_^#shared#^_ @@ -67,7 +67,7 @@ Mastodon - jp.xcscheme_^#shared#^_ orderHint - 15 + 14 Mastodon - nl.xcscheme_^#shared#^_ @@ -87,7 +87,7 @@ Mastodon - zh_Hans.xcscheme_^#shared#^_ orderHint - 16 + 15 Mastodon.xcscheme_^#shared#^_ diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index 43a0036bd..26ba58d55 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -141,8 +141,8 @@ "repositoryURL": "https://github.com/SDWebImage/SDWebImage.git", "state": { "branch": null, - "revision": "d6367439527663d2038ca445a3c3c4e4bac40d60", - "version": "5.12.0" + "revision": "a72df4849408da7e5d3c1b586797b7c601c41d1b", + "version": "5.12.1" } }, { @@ -216,6 +216,15 @@ "revision": "dad97167bf1be16aeecd109130900995dd01c515", "version": "2.6.0" } + }, + { + "package": "UITextView+Placeholder", + "repositoryURL": "https://github.com/MainasuK/UITextView-Placeholder", + "state": { + "branch": null, + "revision": "20f513ded04a040cdf5467f0891849b1763ede3b", + "version": "1.4.1" + } } ] }, diff --git a/Mastodon/Info.plist b/Mastodon/Info.plist index dd63aea2b..f8987fab7 100644 --- a/Mastodon/Info.plist +++ b/Mastodon/Info.plist @@ -30,7 +30,7 @@ CFBundleVersion - 74 + 78 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift index 16dcbbeb6..23630741f 100644 --- a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift +++ b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewController.swift @@ -21,6 +21,19 @@ final class ProfilePagingViewController: TabmanViewController { // MARK: - PageboyViewControllerDelegate + override func pageboyViewController(_ pageboyViewController: PageboyViewController, didCancelScrollToPageAt index: PageboyViewController.PageIndex, returnToPageAt previousIndex: PageboyViewController.PageIndex) { + super.pageboyViewController(pageboyViewController, didCancelScrollToPageAt: index, returnToPageAt: previousIndex) + + // Fix the SDK bug for table view get row selected during swipe but cancel paging + guard previousIndex < viewModel.viewControllers.count else { return } + let viewController = viewModel.viewControllers[previousIndex] + + if let tableView = viewController.scrollView as? UITableView { + for cell in tableView.visibleCells { + cell.setHighlighted(false, animated: false) + } + } + } override func pageboyViewController(_ pageboyViewController: PageboyViewController, didScrollToPageAt index: TabmanViewController.PageIndex, direction: PageboyViewController.NavigationDirection, animated: Bool) { super.pageboyViewController(pageboyViewController, didScrollToPageAt: index, direction: direction, animated: animated) diff --git a/Mastodon/Scene/Search/Search/CollectionViewCell/SearchRecommendTagsCollectionViewCell.swift b/Mastodon/Scene/Search/Search/CollectionViewCell/SearchRecommendTagsCollectionViewCell.swift index e555e1fac..a538d30bf 100644 --- a/Mastodon/Scene/Search/Search/CollectionViewCell/SearchRecommendTagsCollectionViewCell.swift +++ b/Mastodon/Scene/Search/Search/CollectionViewCell/SearchRecommendTagsCollectionViewCell.swift @@ -17,7 +17,7 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell { let hashtagTitleLabel: UILabel = { let label = UILabel() - label.textColor = .white + label.textColor = .label label.font = .systemFont(ofSize: 20, weight: .semibold) label.lineBreakMode = .byTruncatingTail return label @@ -25,18 +25,12 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell { let peopleLabel: UILabel = { let label = UILabel() - label.textColor = .white + label.textColor = .label label.font = .preferredFont(forTextStyle: .body) return label }() - let flameIconView: UIImageView = { - let imageView = UIImageView() - let image = UIImage(systemName: "flame.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .semibold))!.withRenderingMode(.alwaysTemplate) - imageView.image = image - imageView.tintColor = .white - return imageView - }() + let lineChartView = LineChartView() override func prepareForReuse() { super.prepareForReuse() @@ -54,7 +48,7 @@ class SearchRecommendTagsCollectionViewCell: UICollectionViewCell { override var isHighlighted: Bool { didSet { - backgroundColor = isHighlighted ? Asset.Colors.brandBlueDarken20.color : Asset.Colors.brandBlue.color + backgroundColor = isHighlighted ? .systemBackground.withAlphaComponent(0.8) : .systemBackground } } } @@ -68,7 +62,7 @@ extension SearchRecommendTagsCollectionViewCell { } private func configure() { - backgroundColor = Asset.Colors.brandBlue.color + backgroundColor = .systemBackground layer.cornerRadius = 10 layer.cornerCurve = .continuous clipsToBounds = false @@ -98,41 +92,40 @@ extension SearchRecommendTagsCollectionViewCell { containerStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), containerStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor) ]) - - - let horizontalStackView = UIStackView() - horizontalStackView.axis = .horizontal - horizontalStackView.translatesAutoresizingMaskIntoConstraints = false - horizontalStackView.distribution = .fill - hashtagTitleLabel.translatesAutoresizingMaskIntoConstraints = false - hashtagTitleLabel.setContentHuggingPriority(.defaultLow - 1, for: .horizontal) - horizontalStackView.addArrangedSubview(hashtagTitleLabel) - horizontalStackView.setContentHuggingPriority(.required - 1, for: .vertical) - - flameIconView.translatesAutoresizingMaskIntoConstraints = false - horizontalStackView.addArrangedSubview(flameIconView) - flameIconView.setContentHuggingPriority(.required - 1, for: .horizontal) - - containerStackView.addArrangedSubview(horizontalStackView) - peopleLabel.translatesAutoresizingMaskIntoConstraints = false - peopleLabel.setContentHuggingPriority(.defaultLow - 1, for: .vertical) + containerStackView.addArrangedSubview(hashtagTitleLabel) containerStackView.addArrangedSubview(peopleLabel) - containerStackView.setCustomSpacing(SearchViewController.hashtagPeopleTalkingLabelTop, after: horizontalStackView) + + lineChartView.translatesAutoresizingMaskIntoConstraints = false + contentView.addSubview(lineChartView) + NSLayoutConstraint.activate([ + lineChartView.topAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 8), + lineChartView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), + contentView.trailingAnchor.constraint(equalTo: lineChartView.trailingAnchor, constant: 16), + contentView.bottomAnchor.constraint(equalTo: lineChartView.bottomAnchor, constant: 16), + ]) } func config(with tag: Mastodon.Entity.Tag) { hashtagTitleLabel.text = "# " + tag.name - guard let historys = tag.history else { + guard let history = tag.history else { peopleLabel.text = "" return } - let recentHistory = historys.prefix(2) + let recentHistory = history.prefix(2) let peopleAreTalking = recentHistory.compactMap({ Int($0.accounts) }).reduce(0, +) let string = L10n.Scene.Search.Recommend.HashTag.peopleTalking(String(peopleAreTalking)) peopleLabel.text = string - + + lineChartView.data = history + .sorted(by: { $0.day < $1.day }) // latest last + .map { entry in + guard let point = Int(entry.accounts) else { + return .zero + } + return CGFloat(point) + } } } diff --git a/Mastodon/Scene/Search/Search/SearchViewController.swift b/Mastodon/Scene/Search/Search/SearchViewController.swift index 8dcf9cd3b..c72945927 100644 --- a/Mastodon/Scene/Search/Search/SearchViewController.swift +++ b/Mastodon/Scene/Search/Search/SearchViewController.swift @@ -23,9 +23,6 @@ final class SearchViewController: UIViewController, NeedsDependency { public static var hashtagCardHeight: CGFloat { get { - if UIScreen.main.bounds.size.height > 736 { - return 186 - } return 130 } } diff --git a/Mastodon/Scene/Search/Search/View/LineChartView.swift b/Mastodon/Scene/Search/Search/View/LineChartView.swift new file mode 100644 index 000000000..2fb8ac733 --- /dev/null +++ b/Mastodon/Scene/Search/Search/View/LineChartView.swift @@ -0,0 +1,120 @@ +// +// LineChartView.swift +// Mastodon +// +// Created by Cirno MainasuK on 2021-10-18. +// + +import UIKit +import Accelerate +import simd + +final class LineChartView: UIView { + + var data: [CGFloat] = [] { + didSet { + setNeedsLayout() + } + } + + let lineShapeLayer = CAShapeLayer() + let gradientLayer = CAGradientLayer() + let dotShapeLayer = CAShapeLayer() + + override init(frame: CGRect) { + super.init(frame: frame) + _init() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + _init() + } + +} + +extension LineChartView { + private func _init() { + lineShapeLayer.frame = bounds + gradientLayer.frame = bounds + dotShapeLayer.frame = bounds + layer.addSublayer(lineShapeLayer) + layer.addSublayer(gradientLayer) + layer.addSublayer(dotShapeLayer) + + gradientLayer.colors = [ + Asset.Colors.brandBlue.color.withAlphaComponent(0.5).cgColor, + Asset.Colors.brandBlue.color.withAlphaComponent(0).cgColor, + ] + gradientLayer.startPoint = CGPoint(x: 0.5, y: 0) + gradientLayer.endPoint = CGPoint(x: 0.5, y: 1) + } + + override func layoutSubviews() { + super.layoutSubviews() + + lineShapeLayer.frame = bounds + gradientLayer.frame = bounds + dotShapeLayer.frame = bounds + + guard data.count > 1 else { + lineShapeLayer.path = nil + dotShapeLayer.path = nil + gradientLayer.isHidden = true + return + } + gradientLayer.isHidden = false + + // Draw smooth chart + guard let maxDataPoint = data.max() else { + return + } + func calculateY(for point: CGFloat, in frame: CGRect) -> CGFloat { + guard maxDataPoint > 0 else { return .zero } + return (1 - point / maxDataPoint) * frame.height + } + + let segmentCount = data.count - 1 + let segmentWidth = bounds.width / CGFloat(segmentCount) + + let points: [CGPoint] = { + var points: [CGPoint] = [] + var x: CGFloat = 0 + for value in data { + let point = CGPoint(x: x, y: calculateY(for: value, in: bounds)) + points.append(point) + x += segmentWidth + } + return points + }() + + guard let linePath = CurveAlgorithm.shared.createCurvedPath(points) else { return } + let dotPath = UIBezierPath() + + if let last = points.last { + dotPath.addArc(withCenter: last, radius: 3, startAngle: 0, endAngle: 2 * .pi, clockwise: true) + } + + lineShapeLayer.lineWidth = 3 + lineShapeLayer.strokeColor = Asset.Colors.brandBlue.color.cgColor + lineShapeLayer.fillColor = UIColor.clear.cgColor + lineShapeLayer.lineJoin = .round + lineShapeLayer.lineCap = .round + lineShapeLayer.path = linePath.cgPath + + let maskPath = UIBezierPath(cgPath: linePath.cgPath) + maskPath.addLine(to: CGPoint(x: bounds.maxX, y: bounds.maxY)) + maskPath.addLine(to: CGPoint(x: bounds.minX, y: bounds.maxY)) + maskPath.close() + let maskLayer = CAShapeLayer() + maskLayer.path = maskPath.cgPath + maskLayer.fillColor = UIColor.red.cgColor + maskLayer.strokeColor = UIColor.clear.cgColor + maskLayer.lineWidth = 0.0 + gradientLayer.mask = maskLayer + + dotShapeLayer.lineWidth = 3 + dotShapeLayer.fillColor = Asset.Colors.brandBlue.color.cgColor + dotShapeLayer.path = dotPath.cgPath + } +} diff --git a/Mastodon/Vender/CurveAlgorithm.swift b/Mastodon/Vender/CurveAlgorithm.swift new file mode 100644 index 000000000..0ca4c8734 --- /dev/null +++ b/Mastodon/Vender/CurveAlgorithm.swift @@ -0,0 +1,47 @@ +// +// CurveAlgorithm.swift +// +// Ref: https://github.com/nhatminh12369/LineChart/blob/master/LineChart/CurveAlgorithm.swift + +import UIKit + +struct CurvedSegment { + var controlPoint1: CGPoint + var controlPoint2: CGPoint +} + +class CurveAlgorithm { + static let shared = CurveAlgorithm() + + private func controlPointsFrom(points: [CGPoint]) -> [CurvedSegment] { + var result: [CurvedSegment] = [] + + let delta: CGFloat = 0.2 + + // only use horizontal control point + for i in 1.. UIBezierPath? { + let path = UIBezierPath() + path.move(to: dataPoints[0]) + + var curveSegments: [CurvedSegment] = [] + curveSegments = controlPointsFrom(points: dataPoints) + + for i in 1..CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 NSExtension NSExtensionAttributes diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift index e7f095eb3..740001572 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Tag.swift @@ -22,6 +22,7 @@ extension Mastodon.Entity { public let url: String public let history: [History]? + enum CodingKeys: String, CodingKey { case name case url diff --git a/MastodonTests/Info.plist b/MastodonTests/Info.plist index 222a7a1db..1958eb540 100644 --- a/MastodonTests/Info.plist +++ b/MastodonTests/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 diff --git a/MastodonUITests/Info.plist b/MastodonUITests/Info.plist index 222a7a1db..1958eb540 100644 --- a/MastodonUITests/Info.plist +++ b/MastodonUITests/Info.plist @@ -17,6 +17,6 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist index e0a35aca8..f1f14ae01 100644 --- a/NotificationService/Info.plist +++ b/NotificationService/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 NSExtension NSExtensionPointIdentifier diff --git a/ShareActionExtension/Info.plist b/ShareActionExtension/Info.plist index 3cc7eaedd..9edd32f6a 100644 --- a/ShareActionExtension/Info.plist +++ b/ShareActionExtension/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.2.0 CFBundleVersion - 74 + 78 NSExtension NSExtensionAttributes