From e4c38c70e29ea873b77312436845ddd7fc0ca7dd Mon Sep 17 00:00:00 2001 From: CMK Date: Mon, 9 May 2022 11:28:35 +0800 Subject: [PATCH] Release v1.4.1 (#427) * feat: use bundler to install Ruby Gems instead of installing them system-wide using root * chore: install bundler without sudo * Improve tab bar icon vertical alignment * feat: update tabBar UI * chore: update version to 1.4.1 (122) * chore: fix accessibility large content label text missing issue * chore: update version to 1.4.1 (123) * chore: update navigation bar button item assets * fix: compose tabBar button layout raise crash on iPad issue * chore: update version to 1.4.1 (124) * chore: suppress warnings * feat: add navigation pan pop gesture. resolve #407 #419 * chore: update version to 1.4.1 (125) * fix: profile bio line break get trimmed issue. resolve #311 * chore: update version to 1.4.1 (126) Co-authored-by: Marcus Kida Co-authored-by: vollkorntomate --- .github/scripts/setup.sh | 12 +- AppShared/Info.plist | 4 +- Documentation/Setup.md | 14 +- Gemfile | 6 + Gemfile.lock | 109 ++++++++++ Mastodon.xcodeproj/project.pbxproj | 40 ++-- .../xcschemes/xcschememanagement.plist | 2 +- Mastodon/Coordinator/SceneCoordinator.swift | 6 +- .../Onboarding/PickServerSection.swift | 2 +- .../Diffiable/Settings/SettingsSection.swift | 2 +- .../MastodonSDK/Mastodon+Entity+Tag.swift | 19 +- .../Extension/UINavigationController.swift | 16 -- Mastodon/Info.plist | 4 +- .../DataSourceFacade+SearchHistory.swift | 2 +- ...er+NotificationTableViewCellDelegate.swift | 2 +- ...Provider+StatusTableViewCellDelegate.swift | 2 +- ...ider+TableViewControllerNavigateable.swift | 2 +- ...taSourceProvider+UITableViewDelegate.swift | 2 +- .../Scene/Account/AccountViewController.swift | 2 +- .../AutoCompleteViewModel+State.swift | 2 +- .../News/DiscoveryNewsViewModel+State.swift | 2 +- .../HashtagTimelineViewController.swift | 2 +- ...meTimelineViewController+DebugAction.swift | 2 +- .../HomeTimelineViewController.swift | 37 +--- .../HomeTimeline/HomeTimelineViewModel.swift | 1 - .../Header/ProfileHeaderViewModel.swift | 5 +- .../Scene/Profile/ProfileViewController.swift | 26 ++- .../Root/ContentSplitViewController.swift | 4 +- .../Root/MainTab/MainTabBarController.swift | 201 ++++++++++++++---- .../Scene/Root/RootSplitViewController.swift | 6 +- .../Root/Sidebar/SidebarViewController.swift | 5 +- .../Scene/Root/Sidebar/SidebarViewModel.swift | 55 +++-- .../Sidebar/View/SidebarListContentView.swift | 13 +- .../Settings/SettingsViewController.swift | 2 +- ...veStatusBarStyleNavigationController.swift | 34 +++ ...wViewControllerAnimatedTransitioning.swift | 2 + .../APIService/APIService+Thread.swift | 2 +- Mastodon/Service/InstanceService.swift | 2 +- MastodonIntent/Info.plist | 4 +- .../Contents.json | 15 ++ .../Share iOS.pdf | 110 ++++++++++ .../bell.badge.fill.imageset/Contents.json | 15 ++ .../bell.badge.fill.pdf | 94 ++++++++ .../bell.badge.imageset/Contents.json | 15 ++ .../bell.badge.imageset/bell.badge.pdf | 112 ++++++++++ .../bell.fill.imageset/Contents.json | 15 ++ .../bell.fill.imageset/bell.fill.pdf | 88 ++++++++ .../bell.imageset/Contents.json | 15 ++ .../ObjectsAndTools/bell.imageset/bell.pdf | 106 +++++++++ .../gear.imageset/Contents.json | 15 ++ .../ObjectsAndTools/gear.imageset/gear.pdf | 155 ++++++++++++++ .../house.fill.imageset/Contents.json | 15 ++ .../house.fill.imageset/Home-fill.pdf | 85 ++++++++ .../house.imageset/Contents.json | 15 ++ .../ObjectsAndTools/house.imageset/Home.pdf | 105 +++++++++ .../Contents.json | 15 ++ .../Search-Fill.pdf | 83 ++++++++ .../magnifyingglass.imageset/Contents.json | 15 ++ .../magnifyingglass.imageset/Search.pdf | 83 ++++++++ .../square.and.pencil.imageset/Contents.json | 15 ++ .../square.and.pencil.pdf | 93 ++++++++ .../MastodonAsset/Generated/Assets.swift | 11 + .../MastodonUI/Extension/UIImage.swift | 18 ++ MastodonTests/Info.plist | 4 +- MastodonUITests/Info.plist | 4 +- NotificationService/Info.plist | 4 +- ShareActionExtension/Info.plist | 4 +- update_localization.sh | 2 +- 68 files changed, 1779 insertions(+), 202 deletions(-) create mode 100644 Gemfile create mode 100644 Gemfile.lock delete mode 100644 Mastodon/Extension/UINavigationController.swift create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Share iOS.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/bell.badge.fill.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/bell.badge.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/bell.fill.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/bell.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/gear.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Home-fill.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Home.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Search-Fill.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Search.pdf create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/Contents.json create mode 100644 MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/square.and.pencil.pdf create mode 100644 MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift diff --git a/.github/scripts/setup.sh b/.github/scripts/setup.sh index 0c2612d51..9b52d5b9e 100755 --- a/.github/scripts/setup.sh +++ b/.github/scripts/setup.sh @@ -1,9 +1,13 @@ #!/bin/bash -sudo gem install cocoapods-keys +# Install Ruby Bundler +gem install bundler:2.3.11 + +# Install Ruby Gems +bundle install # stub keys. DO NOT use in production -pod keys set notification_endpoint "" -pod keys set notification_endpoint_debug "" +bundle exec pod keys set notification_endpoint "" +bundle exec pod keys set notification_endpoint_debug "" -pod install +bundle exec pod install diff --git a/AppShared/Info.plist b/AppShared/Info.plist index a1528e2c5..92f442892 100644 --- a/AppShared/Info.plist +++ b/AppShared/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 diff --git a/Documentation/Setup.md b/Documentation/Setup.md index ede9d4862..1c2f0a6c5 100644 --- a/Documentation/Setup.md +++ b/Documentation/Setup.md @@ -12,12 +12,13 @@ Intell the latest version of Xcode from the App Store or Apple Developer Downloa This guide may not suit your machine and actually setup procedure may change in the future. Please file the issue or Pull Request if there are any problems. ## CocoaPods -The app use [CocoaPods]() and [CocoaPods-Keys](https://github.com/orta/cocoapods-keys). The M1 Mac needs virtual ruby env to workaround compatibility issues. +The app use [CocoaPods]() and [CocoaPods-Keys](https://github.com/orta/cocoapods-keys). Ruby Gems are managed through Bundler. The M1 Mac needs virtual ruby env to workaround compatibility issues. #### Intel Mac ```zsh -sudo gem install cocoapods cocoapods-keys +gem install bundler +bundle install ``` #### M1 Mac @@ -40,18 +41,19 @@ rbenv global 3.0.3 ruby --version # > ruby 3.0.3p157 (2021-11-24 revision 3fb7d2cadc) [arm64-darwin21] -sudo gem install cocoapods cocoapods-keys +gem install bundler +bundle install ``` ## Bootstrap ```zsh # make a clean build -sudo gem install cocoapods-clean -pod clean +bundle install +bundle exec pod clean # make install -pod install --repo-update +bundle exec pod install --repo-update # open workspace open Mastodon.xcworkspace diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..48aae3d82 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source "https://rubygems.org" + +gem "cocoapods" +gem "cocoapods-clean" +gem "cocoapods-keys" + diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..b27a44a97 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,109 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.5) + rexml + RubyInline (3.12.5) + ZenTest (~> 4.3) + ZenTest (4.12.1) + activesupport (6.1.5.1) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + addressable (2.8.0) + public_suffix (>= 2.0.2, < 5.0) + algoliasearch (1.27.5) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + claide (1.1.0) + cocoapods (1.11.3) + addressable (~> 2.8) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.11.3) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.4.0, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.8.0) + nap (~> 1.0) + ruby-macho (>= 1.0, < 3.0) + xcodeproj (>= 1.21.0, < 2.0) + cocoapods-clean (0.0.1) + cocoapods-core (1.11.3) + activesupport (>= 5.0, < 7) + addressable (~> 2.8) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + netrc (~> 0.11) + public_suffix (~> 4.0) + typhoeus (~> 1.0) + cocoapods-deintegrate (1.0.5) + cocoapods-downloader (1.6.3) + cocoapods-keys (2.2.1) + dotenv + osx_keychain + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.1) + cocoapods-trunk (1.6.0) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.2.0) + colored2 (3.1.2) + concurrent-ruby (1.1.10) + dotenv (2.7.6) + escape (0.0.4) + ethon (0.15.0) + ffi (>= 1.15.0) + ffi (1.15.5) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.8.3) + i18n (1.10.0) + concurrent-ruby (~> 1.0) + json (2.6.1) + minitest (5.15.0) + molinillo (0.8.0) + nanaimo (0.3.0) + nap (1.1.0) + netrc (0.11.0) + osx_keychain (1.0.2) + RubyInline (~> 3) + public_suffix (4.0.7) + rexml (3.2.5) + ruby-macho (2.5.1) + typhoeus (1.4.0) + ethon (>= 0.9.0) + tzinfo (2.0.4) + concurrent-ruby (~> 1.0) + xcodeproj (1.21.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.3.0) + rexml (~> 3.2.4) + zeitwerk (2.5.4) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods + cocoapods-clean + cocoapods-keys + +BUNDLED WITH + 2.3.11 diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index fcba16b23..d5f5cbd79 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -537,7 +537,6 @@ DBCBED1726132DB500B49291 /* UserTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBED1626132DB500B49291 /* UserTimelineViewModel+Diffable.swift */; }; DBCBED1D26132E1A00B49291 /* StatusFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBED1C26132E1A00B49291 /* StatusFetchedResultsController.swift */; }; DBCC3B30261440A50045B23D /* UITabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCC3B2F261440A50045B23D /* UITabBarController.swift */; }; - DBCC3B36261440BA0045B23D /* UINavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCC3B35261440BA0045B23D /* UINavigationController.swift */; }; DBCC3B8F26148F7B0045B23D /* CachedProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCC3B8E26148F7B0045B23D /* CachedProfileViewModel.swift */; }; DBCC3B9526157E6E0045B23D /* APIService+Relationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCC3B9426157E6E0045B23D /* APIService+Relationship.swift */; }; DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCCC71D25F73297007E1AB6 /* APIService+Reblog.swift */; }; @@ -1302,7 +1301,6 @@ DBCBED1626132DB500B49291 /* UserTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserTimelineViewModel+Diffable.swift"; sourceTree = ""; }; DBCBED1C26132E1A00B49291 /* StatusFetchedResultsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusFetchedResultsController.swift; sourceTree = ""; }; DBCC3B2F261440A50045B23D /* UITabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITabBarController.swift; sourceTree = ""; }; - DBCC3B35261440BA0045B23D /* UINavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UINavigationController.swift; sourceTree = ""; }; DBCC3B8E26148F7B0045B23D /* CachedProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachedProfileViewModel.swift; sourceTree = ""; }; DBCC3B9426157E6E0045B23D /* APIService+Relationship.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Relationship.swift"; sourceTree = ""; }; DBCCC71D25F73297007E1AB6 /* APIService+Reblog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Reblog.swift"; sourceTree = ""; }; @@ -2792,7 +2790,6 @@ 2D84350425FF858100EECE90 /* UIScrollView.swift */, DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */, DBCC3B2F261440A50045B23D /* UITabBarController.swift */, - DBCC3B35261440BA0045B23D /* UINavigationController.swift */, DB73BF4827140BA300781945 /* UICollectionViewDiffableDataSource.swift */, DB73BF4A27140C0800781945 /* UITableViewDiffableDataSource.swift */, ); @@ -4029,7 +4026,6 @@ DB9D7C21269824B80054B3DF /* APIService+Filter.swift in Sources */, 2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */, DB0FCB842796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift in Sources */, - DBCC3B36261440BA0045B23D /* UINavigationController.swift in Sources */, DB0FCB68279507EF006C02E2 /* DataSourceFacade+Meta.swift in Sources */, DB63F75C279956D000455B82 /* Persistence+Tag.swift in Sources */, 2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */, @@ -4711,7 +4707,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4741,7 +4737,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4849,11 +4845,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 121; + DYLIB_CURRENT_VERSION = 126; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4880,11 +4876,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 121; + DYLIB_CURRENT_VERSION = 126; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4908,7 +4904,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4932,7 +4928,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4956,7 +4952,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4980,7 +4976,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5067,7 +5063,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -5134,11 +5130,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 121; + DYLIB_CURRENT_VERSION = 126; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5162,7 +5158,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5185,7 +5181,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5209,7 +5205,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5233,7 +5229,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5256,7 +5252,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 121; + CURRENT_PROJECT_VERSION = 126; 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 979898bbd..07a847a0c 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -129,7 +129,7 @@ ShareActionExtension.xcscheme_^#shared#^_ orderHint - 22 + 26 SuppressBuildableAutocreation diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 1f8030014..5e7fbf472 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -309,7 +309,7 @@ extension SceneCoordinator { if scene.isOnboarding { return OnboardingNavigationController(rootViewController: viewController) } else { - return UINavigationController(rootViewController: viewController) + return AdaptiveStatusBarStyleNavigationController(rootViewController: viewController) } }() modalNavigationController.modalPresentationCapturesStatusBarAppearance = true @@ -368,10 +368,10 @@ extension SceneCoordinator { splitViewController?.contentSplitViewController.currentSupplementaryTab = tab splitViewController?.compactMainTabBarViewController.selectedIndex = tab.rawValue - splitViewController?.compactMainTabBarViewController.currentTab.value = tab + splitViewController?.compactMainTabBarViewController.currentTab = tab tabBarController.selectedIndex = tab.rawValue - tabBarController.currentTab.value = tab + tabBarController.currentTab = tab } } diff --git a/Mastodon/Diffiable/Onboarding/PickServerSection.swift b/Mastodon/Diffiable/Onboarding/PickServerSection.swift index 5faaefbcc..01a31f6f6 100644 --- a/Mastodon/Diffiable/Onboarding/PickServerSection.swift +++ b/Mastodon/Diffiable/Onboarding/PickServerSection.swift @@ -29,7 +29,7 @@ extension PickServerSection { weak dependency, weak pickServerCellDelegate ] tableView, indexPath, item -> UITableViewCell? in - guard let dependency = dependency else { return nil } + guard let _ = dependency else { return nil } switch item { case .header: let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: OnboardingHeadlineTableViewCell.self), for: indexPath) as! OnboardingHeadlineTableViewCell diff --git a/Mastodon/Diffiable/Settings/SettingsSection.swift b/Mastodon/Diffiable/Settings/SettingsSection.swift index adc7140be..6925303d8 100644 --- a/Mastodon/Diffiable/Settings/SettingsSection.swift +++ b/Mastodon/Diffiable/Settings/SettingsSection.swift @@ -51,7 +51,7 @@ extension SettingsSection { } cell.delegate = settingsAppearanceTableViewCellDelegate return cell - case .appearancePreference(let record, let appearanceType): + case .appearancePreference(let record, _): let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsToggleTableViewCell.self), for: indexPath) as! SettingsToggleTableViewCell cell.delegate = settingsToggleCellDelegate managedObjectContext.performAndWait { diff --git a/Mastodon/Extension/MastodonSDK/Mastodon+Entity+Tag.swift b/Mastodon/Extension/MastodonSDK/Mastodon+Entity+Tag.swift index e217d3a82..6251d1814 100644 --- a/Mastodon/Extension/MastodonSDK/Mastodon+Entity+Tag.swift +++ b/Mastodon/Extension/MastodonSDK/Mastodon+Entity+Tag.swift @@ -7,13 +7,12 @@ import MastodonSDK -extension Mastodon.Entity.Tag: Hashable { - public func hash(into hasher: inout Hasher) { - hasher.combine(name) - } - - public static func == (lhs: Mastodon.Entity.Tag, rhs: Mastodon.Entity.Tag) -> Bool { - return lhs.name == rhs.name - } -} - +//extension Mastodon.Entity.Tag: Hashable { +// public func hash(into hasher: inout Hasher) { +// hasher.combine(name) +// } +// +// public static func == (lhs: Mastodon.Entity.Tag, rhs: Mastodon.Entity.Tag) -> Bool { +// return lhs.name == rhs.name +// } +//} diff --git a/Mastodon/Extension/UINavigationController.swift b/Mastodon/Extension/UINavigationController.swift deleted file mode 100644 index 9a9c44ab3..000000000 --- a/Mastodon/Extension/UINavigationController.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// UINavigationController.swift -// Mastodon -// -// Created by MainasuK Cirno on 2021-3-31. -// - -import UIKit - -// This not works! -// SeeAlso: `AdaptiveStatusBarStyleNavigationController` -extension UINavigationController { - open override var childForStatusBarStyle: UIViewController? { - return visibleViewController - } -} diff --git a/Mastodon/Info.plist b/Mastodon/Info.plist index 6dec562da..c93fd9a65 100644 --- a/Mastodon/Info.plist +++ b/Mastodon/Info.plist @@ -30,7 +30,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleURLTypes @@ -43,7 +43,7 @@ CFBundleVersion - 121 + 126 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift index cbc6bf348..8beaabbae 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+SearchHistory.swift @@ -99,7 +99,7 @@ extension DataSourceFacade { try await managedObjectContext.performChanges { guard let authenticationBox = _authenticationBox else { return } - guard let me = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return } + guard let _ = authenticationBox.authenticationRecord.object(in: managedObjectContext)?.user else { return } let request = SearchHistory.sortedFetchRequest request.predicate = SearchHistory.predicate( domain: authenticationBox.domain, diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift index f6e58673b..ca7fdeb18 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+NotificationTableViewCellDelegate.swift @@ -486,7 +486,7 @@ extension NotificationTableViewCellDelegate where Self: DataSourceProvider { provider: self, user: user ) - case .notification(let notification): + case .notification: assertionFailure("TODO") default: assertionFailure("TODO") diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index 9e5838e77..f00e14840 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -494,7 +494,7 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider { provider: self, user: user ) - case .notification(let notification): + case .notification: assertionFailure("TODO") default: assertionFailure("TODO") diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+TableViewControllerNavigateable.swift b/Mastodon/Protocol/Provider/DataSourceProvider+TableViewControllerNavigateable.swift index f7e50cff8..50fa17866 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+TableViewControllerNavigateable.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+TableViewControllerNavigateable.swift @@ -138,7 +138,7 @@ extension TableViewControllerNavigateableCore where Self: DataSourceProvider { target: .status, status: record ) - case .notification(let record): + case .notification: assertionFailure() default: assertionFailure() diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift index 3968df110..c00c36971 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+UITableViewDelegate.swift @@ -93,7 +93,7 @@ extension UITableViewDelegate where Self: DataSourceProvider & MediaPreviewableV guard let image = mediaView.thumbnail(), let assetURLString = mediaView.configuration?.assetURL, let assetURL = URL(string: assetURLString), - let resourceType = mediaView.configuration?.resourceType + let _ = mediaView.configuration?.resourceType else { // not provide preview unless thumbnail ready return nil diff --git a/Mastodon/Scene/Account/AccountViewController.swift b/Mastodon/Scene/Account/AccountViewController.swift index 42c9e1d62..20d7b26a1 100644 --- a/Mastodon/Scene/Account/AccountViewController.swift +++ b/Mastodon/Scene/Account/AccountViewController.swift @@ -118,7 +118,7 @@ extension AccountListViewController { // the presentingViewController may deinit. // Hold it and check the window to prevent PanModel crash - guard let presentingViewController = presentingViewController else { return } + guard let _ = presentingViewController else { return } guard self.view.window != nil else { return } self.hasLoaded = true diff --git a/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel+State.swift b/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel+State.swift index ebda78a1e..632b57b66 100644 --- a/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel+State.swift +++ b/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel+State.swift @@ -77,7 +77,7 @@ extension AutoCompleteViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + guard let viewModel = viewModel, let _ = stateMachine else { return } let searchText = viewModel.inputText.value let searchType = AutoCompleteViewModel.SearchType(inputText: searchText) ?? .default diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift index 8da975de2..92b84d176 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewModel+State.swift @@ -68,7 +68,7 @@ extension DiscoveryNewsViewModel.State { override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + guard let _ = viewModel, let stateMachine = stateMachine else { return } stateMachine.enter(Loading.self) } diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index b3a8ca040..3b8db5d56 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -28,7 +28,7 @@ final class HashtagTimelineViewController: UIViewController, NeedsDependency, Me let composeBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() - barButtonItem.image = UIImage(systemName: "square.and.pencil")?.withRenderingMode(.alwaysTemplate) + barButtonItem.image = Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) return barButtonItem }() diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift index 8b6eb9f42..4fae66d33 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift @@ -186,7 +186,7 @@ extension HomeTimelineViewController { } func match(item: StatusItem) -> Bool { - let authenticationBox = AppContext.shared.authenticationService.activeMastodonAuthenticationBox.value + // let authenticationBox = AppContext.shared.authenticationService.activeMastodonAuthenticationBox.value switch item { case .feed(let record): guard let feed = record.object(in: AppContext.shared.managedObjectContext) else { return false } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 549552725..64d3d5941 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -51,19 +51,11 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let settingBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() barButtonItem.tintColor = ThemeService.tintColor - barButtonItem.image = UIImage(systemName: "gear")?.withRenderingMode(.alwaysTemplate) + barButtonItem.image = Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate) barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.settings return barButtonItem }() - let composeBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem() - barButtonItem.tintColor = ThemeService.tintColor - barButtonItem.image = UIImage(systemName: "square.and.pencil")?.withRenderingMode(.alwaysTemplate) - barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.compose - return barButtonItem - }() - let tableView: UITableView = { let tableView = ControlContainableTableView() tableView.register(StatusTableViewCell.self, forCellReuseIdentifier: String(describing: StatusTableViewCell.self)) @@ -109,14 +101,14 @@ extension HomeTimelineViewController { guard let self = self else { return } #if DEBUG // display debug menu - self.navigationItem.leftBarButtonItem = { + self.navigationItem.rightBarButtonItem = { let barButtonItem = UIBarButtonItem() barButtonItem.image = UIImage(systemName: "ellipsis.circle") barButtonItem.menu = self.debugMenu return barButtonItem }() #else - self.navigationItem.leftBarButtonItem = displaySettingBarButtonItem ? self.settingBarButtonItem : nil + self.navigationItem.rightBarButtonItem = displaySettingBarButtonItem ? self.settingBarButtonItem : nil #endif } .store(in: &disposeBag) @@ -133,16 +125,6 @@ extension HomeTimelineViewController { titleView.button.menu = self.debugMenu #endif - viewModel.$displayComposeBarButtonItem - .receive(on: DispatchQueue.main) - .sink { [weak self] displayComposeBarButtonItem in - guard let self = self else { return } - self.navigationItem.rightBarButtonItem = displayComposeBarButtonItem ? self.composeBarButtonItem : nil - } - .store(in: &disposeBag) - composeBarButtonItem.target = self - composeBarButtonItem.action = #selector(HomeTimelineViewController.composeBarButtonItemPressed(_:)) - navigationItem.titleView = titleView titleView.delegate = self @@ -411,18 +393,7 @@ extension HomeTimelineViewController { let settingsViewModel = SettingsViewModel(context: context, setting: setting) coordinator.present(scene: .settings(viewModel: settingsViewModel), from: self, transition: .modal(animated: true, completion: nil)) } - - @objc private func composeBarButtonItemPressed(_ sender: UIBarButtonItem) { - os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) - guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return } - let composeViewModel = ComposeViewModel( - context: context, - composeKind: .post, - authenticationBox: authenticationBox - ) - coordinator.present(scene: .compose(viewModel: composeViewModel), from: self, transition: .modal(animated: true, completion: nil)) - } - + @objc private func refreshControlValueChanged(_ sender: UIRefreshControl) { guard viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.Loading.self) else { sender.endRefreshing() diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index b2c280fb5..be7de3a5a 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -33,7 +33,6 @@ final class HomeTimelineViewModel: NSObject { @Published var lastAutomaticFetchTimestamp: Date? = nil @Published var scrollPositionRecord: ScrollPositionRecord? = nil @Published var displaySettingBarButtonItem = true - @Published var displayComposeBarButtonItem = true weak var tableView: UITableView? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? diff --git a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift index 7f7b0dd00..8bdce2a6d 100644 --- a/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift +++ b/Mastodon/Scene/Profile/Header/ProfileHeaderViewModel.swift @@ -90,7 +90,10 @@ extension ProfileHeaderViewModel { extension ProfileHeaderViewModel { static func normalize(note: String?) -> String? { - guard let note = note?.trimmingCharacters(in: .whitespacesAndNewlines),!note.isEmpty else { + let _note = note?.replacingOccurrences(of: "
|
", with: "\u{2028}", options: .regularExpression, range: nil) + .replacingOccurrences(of: "

", with: "

\u{2029}", range: nil) + .trimmingCharacters(in: .whitespacesAndNewlines) + guard let note = _note, !note.isEmpty else { return nil } diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 55a952b0e..b376ebcf9 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -42,19 +42,34 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi }() private(set) lazy var settingBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "gear"), style: .plain, target: self, action: #selector(ProfileViewController.settingBarButtonItemPressed(_:))) + let barButtonItem = UIBarButtonItem( + image: Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate), + style: .plain, + target: self, + action: #selector(ProfileViewController.settingBarButtonItemPressed(_:)) + ) barButtonItem.tintColor = .white return barButtonItem }() private(set) lazy var shareBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "square.and.arrow.up"), style: .plain, target: self, action: #selector(ProfileViewController.shareBarButtonItemPressed(_:))) + let barButtonItem = UIBarButtonItem( + image: Asset.Arrow.squareAndArrowUp.image.withRenderingMode(.alwaysTemplate), + style: .plain, + target: self, + action: #selector(ProfileViewController.shareBarButtonItemPressed(_:)) + ) barButtonItem.tintColor = .white return barButtonItem }() private(set) lazy var favoriteBarButtonItem: UIBarButtonItem = { - let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "star"), style: .plain, target: self, action: #selector(ProfileViewController.favoriteBarButtonItemPressed(_:))) + let barButtonItem = UIBarButtonItem( + image: Asset.ObjectsAndTools.star.image.withRenderingMode(.alwaysTemplate), + style: .plain, + target: self, + action: #selector(ProfileViewController.favoriteBarButtonItemPressed(_:)) + ) barButtonItem.tintColor = .white return barButtonItem }() @@ -619,7 +634,7 @@ extension ProfileViewController { return nil } let name = user.displayNameWithFallback - let record = ManagedObjectRecord(objectID: user.objectID) + let _ = ManagedObjectRecord(objectID: user.objectID) let menu = MastodonMenu.setupMenu( actions: [ .muteUser(.init(name: name, isMuting: self.viewModel.isMuting.value)), @@ -634,7 +649,7 @@ extension ProfileViewController { .sink { [weak self] completion in guard let self = self else { return } switch completion { - case .failure(let error): + case .failure: self.moreMenuBarButtonItem.menu = nil case .finished: break @@ -938,6 +953,7 @@ extension ProfileViewController: ProfileHeaderViewDelegate { viewModel.isUpdating.value = true Task { do { + // TODO: handle error _ = try await viewModel.updateProfileInfo( headerProfileInfo: profileHeaderViewModel.editProfileInfo, aboutProfileInfo: profileAboutViewModel.editProfileInfo diff --git a/Mastodon/Scene/Root/ContentSplitViewController.swift b/Mastodon/Scene/Root/ContentSplitViewController.swift index 5a34e1ed8..03e203107 100644 --- a/Mastodon/Scene/Root/ContentSplitViewController.swift +++ b/Mastodon/Scene/Root/ContentSplitViewController.swift @@ -38,7 +38,6 @@ final class ContentSplitViewController: UIViewController, NeedsDependency { private(set) lazy var mainTabBarController: MainTabBarController = { let mainTabBarController = MainTabBarController(context: context, coordinator: coordinator) if let homeTimelineViewController = mainTabBarController.viewController(of: HomeTimelineViewController.self) { - homeTimelineViewController.viewModel.displayComposeBarButtonItem = false homeTimelineViewController.viewModel.displaySettingBarButtonItem = false } return mainTabBarController @@ -83,7 +82,8 @@ extension ContentSplitViewController { .sink(receiveValue: { [weak self] tab in guard let self = self else { return } self.mainTabBarController.selectedIndex = tab.rawValue - self.mainTabBarController.currentTab.value = tab + self.mainTabBarController.currentTab = tab + self.sidebarViewController.viewModel.currentTab = tab }) .store(in: &disposeBag) } diff --git a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift index 7ea748a60..8970e2f29 100644 --- a/Mastodon/Scene/Root/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/Root/MainTab/MainTabBarController.swift @@ -22,14 +22,29 @@ class MainTabBarController: UITabBarController { weak var context: AppContext! weak var coordinator: SceneCoordinator! + let composeButttonShadowBackgroundContainer = ShadowBackgroundContainer() + let composeButton: UIButton = { + let button = UIButton() + button.setImage(Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate), for: .normal) + button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Label.primary.color), for: .normal) + button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Label.primary.color.withAlphaComponent(0.8)), for: .highlighted) + button.tintColor = Asset.Colors.Label.primaryReverse.color + button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 12, bottom: 6, right: 12) + button.layer.masksToBounds = true + button.layer.cornerCurve = .continuous + button.layer.cornerRadius = 8 + return button + }() + static let avatarButtonSize = CGSize(width: 25, height: 25) let avatarButton = CircleAvatarButton() - var currentTab = CurrentValueSubject(.home) + @Published var currentTab: Tab = .home enum Tab: Int, CaseIterable { case home case search + case compose case notification case me @@ -41,6 +56,7 @@ class MainTabBarController: UITabBarController { switch self { case .home: return L10n.Common.Controls.Tabs.home case .search: return L10n.Common.Controls.Tabs.search + case .compose: return L10n.Common.Controls.Actions.compose case .notification: return L10n.Common.Controls.Tabs.notification case .me: return L10n.Common.Controls.Tabs.profile } @@ -48,28 +64,41 @@ class MainTabBarController: UITabBarController { var image: UIImage { switch self { - case .home: return UIImage(systemName: "house.fill")! - case .search: return UIImage(systemName: "magnifyingglass")! - case .notification: return UIImage(systemName: "bell.fill")! + case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate) + case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate) + case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) + case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + case .me: return UIImage(systemName: "person")! + } + } + + var selectedImage: UIImage { + switch self { + case .home: return Asset.ObjectsAndTools.houseFill.image.withRenderingMode(.alwaysTemplate) + case .search: return Asset.ObjectsAndTools.magnifyingglassFill.image.withRenderingMode(.alwaysTemplate) + case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) + case .notification: return Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) case .me: return UIImage(systemName: "person.fill")! } } var largeImage: UIImage { switch self { - case .home: return UIImage(systemName: "house.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! - case .search: return UIImage(systemName: "magnifyingglass", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! - case .notification: return UIImage(systemName: "bell.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! - case .me: return UIImage(systemName: "person.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! + case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) + case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) + case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) + case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate).resized(size: CGSize(width: 80, height: 80)) + case .me: return UIImage(systemName: "person", withConfiguration: UIImage.SymbolConfiguration(pointSize: 80))! } } var sidebarImage: UIImage { switch self { - case .home: return UIImage(systemName: "house")! - case .search: return UIImage(systemName: "magnifyingglass")! - case .notification: return UIImage(systemName: "bell")! - case .me: return UIImage(systemName: "person.fill")! + case .home: return Asset.ObjectsAndTools.house.image.withRenderingMode(.alwaysTemplate) + case .search: return Asset.ObjectsAndTools.magnifyingglass.image.withRenderingMode(.alwaysTemplate) + case .compose: return Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate) + case .notification: return Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + case .me: return UIImage(systemName: "person")! } } @@ -86,6 +115,8 @@ class MainTabBarController: UITabBarController { _viewController.context = context _viewController.coordinator = coordinator viewController = _viewController + case .compose: + viewController = UIViewController() case .notification: let _viewController = NotificationViewController() _viewController.context = context @@ -143,24 +174,30 @@ extension MainTabBarController { } .store(in: &disposeBag) + // seealso: `ThemeService.apply(theme:)` let tabs = Tab.allCases let viewControllers: [UIViewController] = tabs.map { tab in let viewController = tab.viewController(context: context, coordinator: coordinator) viewController.tabBarItem.tag = tab.tag - viewController.tabBarItem.title = tab.title - viewController.tabBarItem.image = tab.image + viewController.tabBarItem.title = tab.title // needs for acessiblity large content label + viewController.tabBarItem.image = tab.image.imageWithoutBaseline() + viewController.tabBarItem.selectedImage = tab.selectedImage.imageWithoutBaseline() + viewController.tabBarItem.largeContentSizeImage = tab.largeImage.imageWithoutBaseline() viewController.tabBarItem.accessibilityLabel = tab.title - viewController.tabBarItem.largeContentSizeImage = tab.largeImage viewController.tabBarItem.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0) + + switch tab { + case .compose: + viewController.tabBarItem.isEnabled = false + default: + break + } + return viewController } _viewControllers = viewControllers setViewControllers(viewControllers, animated: false) selectedIndex = 0 - - UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : UIColor.clear], for: .normal) - UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : UIColor.clear], for: .highlighted) - UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : UIColor.clear], for: .selected) context.apiService.error .receive(on: DispatchQueue.main) @@ -208,13 +245,15 @@ extension MainTabBarController { } .store(in: &disposeBag) - // handle push notification. toggle entry when finish fetch latest notification - Publishers.CombineLatest( + // handle push notification. + // toggle entry when finish fetch latest notification + Publishers.CombineLatest3( context.authenticationService.activeMastodonAuthentication, - context.notificationService.unreadNotificationCountDidUpdate + context.notificationService.unreadNotificationCountDidUpdate, + $currentTab ) .receive(on: DispatchQueue.main) - .sink { [weak self] authentication, _ in + .sink { [weak self] authentication, _, currentTab in guard let self = self else { return } guard let notificationViewController = self.notificationViewController else { return } @@ -223,12 +262,19 @@ extension MainTabBarController { return count > 0 } ?? false - let image = hasUnreadPushNotification ? UIImage(systemName: "bell.badge.fill")! : UIImage(systemName: "bell.fill")! - notificationViewController.tabBarItem.image = image - notificationViewController.navigationController?.tabBarItem.image = image + let image: UIImage = { + if currentTab == .notification { + return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadgeFill.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) + } else { + return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadge.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + } + }() + notificationViewController.tabBarItem.image = image.imageWithoutBaseline() + notificationViewController.navigationController?.tabBarItem.image = image.imageWithoutBaseline() } .store(in: &disposeBag) + layoutComposeButton() layoutAvatarButton() $avatarURL @@ -280,7 +326,7 @@ extension MainTabBarController { } .store(in: &disposeBag) - currentTab + $currentTab .receive(on: DispatchQueue.main) .sink { [weak self] tab in guard let self = self else { return } @@ -290,6 +336,8 @@ extension MainTabBarController { updateTabBarDisplay() + composeButton.addTarget(self, action: #selector(MainTabBarController.composeButtonDidPressed(_:)), for: .touchUpInside) + #if DEBUG // Debug Register viewController // Task { @MainActor in @@ -307,23 +355,25 @@ extension MainTabBarController { super.traitCollectionDidChange(previousTraitCollection) updateTabBarDisplay() + updateComposeButtonAppearance() updateAvatarButtonAppearance() } } extension MainTabBarController { - private func updateTabBarDisplay() { - switch traitCollection.horizontalSizeClass { - case .compact: - tabBar.isHidden = false - default: - tabBar.isHidden = true - } + + @objc private func composeButtonDidPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return } + let composeViewModel = ComposeViewModel( + context: context, + composeKind: .post, + authenticationBox: authenticationBox + ) + coordinator.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil)) } -} - -extension MainTabBarController { + @objc private func tabBarLongPressGestureRecognizerHandler(_ sender: UILongPressGestureRecognizer) { guard sender.state == .began else { return } @@ -351,6 +401,59 @@ extension MainTabBarController { } extension MainTabBarController { + + private func updateTabBarDisplay() { + switch traitCollection.horizontalSizeClass { + case .compact: + tabBar.isHidden = false + composeButttonShadowBackgroundContainer.isHidden = false + default: + tabBar.isHidden = true + composeButttonShadowBackgroundContainer.isHidden = true + } + } + + private func layoutComposeButton() { + guard composeButton.superview == nil else { return } + + let _composeTabItem = self.tabBar.items?.first { item in item.tag == Tab.compose.tag } + guard let composeTabItem = _composeTabItem else { return } + guard let view = composeTabItem.value(forKey: "view") as? UIView else { + return + } + + let _anchorImageView = view.subviews.first { subview in subview is UIImageView } as? UIImageView + guard let anchorImageView = _anchorImageView else { + assertionFailure() + return + } + anchorImageView.alpha = 0 + + composeButttonShadowBackgroundContainer.translatesAutoresizingMaskIntoConstraints = false + self.view.addSubview(composeButttonShadowBackgroundContainer) // add to tabBar will crash on iPad when size class changing + NSLayoutConstraint.activate([ + composeButttonShadowBackgroundContainer.centerXAnchor.constraint(equalTo: anchorImageView.centerXAnchor), + composeButttonShadowBackgroundContainer.centerYAnchor.constraint(equalTo: anchorImageView.centerYAnchor), + ]) + composeButttonShadowBackgroundContainer.cornerRadius = composeButton.layer.cornerRadius + + composeButton.translatesAutoresizingMaskIntoConstraints = false + composeButttonShadowBackgroundContainer.addSubview(composeButton) + NSLayoutConstraint.activate([ + composeButton.topAnchor.constraint(equalTo: composeButttonShadowBackgroundContainer.topAnchor), + composeButton.leadingAnchor.constraint(equalTo: composeButttonShadowBackgroundContainer.leadingAnchor), + composeButton.trailingAnchor.constraint(equalTo: composeButttonShadowBackgroundContainer.trailingAnchor), + composeButton.bottomAnchor.constraint(equalTo: composeButttonShadowBackgroundContainer.bottomAnchor), + ]) + composeButton.setContentHuggingPriority(.required - 1, for: .horizontal) + composeButton.setContentHuggingPriority(.required - 1, for: .vertical) + } + + private func updateComposeButtonAppearance() { + composeButton.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Label.primary.color), for: .normal) + composeButton.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Label.primary.color.withAlphaComponent(0.8)), for: .highlighted) + } + private func layoutAvatarButton() { guard avatarButton.superview == nil else { return } @@ -370,8 +473,8 @@ extension MainTabBarController { self.avatarButton.translatesAutoresizingMaskIntoConstraints = false view.addSubview(self.avatarButton) NSLayoutConstraint.activate([ - self.avatarButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), - self.avatarButton.centerYAnchor.constraint(equalTo: anchorImageView.centerYAnchor, constant: 1.5), // 1.5pt offset + self.avatarButton.centerXAnchor.constraint(equalTo: anchorImageView.centerXAnchor), + self.avatarButton.centerYAnchor.constraint(equalTo: anchorImageView.centerYAnchor), self.avatarButton.widthAnchor.constraint(equalToConstant: MainTabBarController.avatarButtonSize.width).priority(.required - 1), self.avatarButton.heightAnchor.constraint(equalToConstant: MainTabBarController.avatarButtonSize.height).priority(.required - 1), ]) @@ -381,9 +484,10 @@ extension MainTabBarController { } private func updateAvatarButtonAppearance() { - avatarButton.borderColor = currentTab.value == .me ? .label : .systemFill + avatarButton.borderColor = currentTab == .me ? .label : .systemFill avatarButton.setNeedsLayout() } + } extension MainTabBarController { @@ -403,11 +507,12 @@ extension MainTabBarController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: select %s", ((#file as NSString).lastPathComponent), #line, #function, viewController.debugDescription) defer { - if let tab = Tab(rawValue: tabBarController.selectedIndex) { - currentTab.value = tab + if let tab = Tab(rawValue: viewController.tabBarItem.tag) { + currentTab = tab } } - guard currentTab.value.rawValue == tabBarController.selectedIndex, + // assert index is as same as the tab rawValue + guard currentTab.rawValue == tabBarController.selectedIndex, let navigationController = viewController as? UINavigationController, navigationController.viewControllers.count == 1, let scrollViewContainer = navigationController.topViewController as? ScrollViewContainer else { @@ -478,7 +583,13 @@ extension MainTabBarController { var switchToTabKeyCommands: [UIKeyCommand] { var commands: [UIKeyCommand] = [] - for (i, tab) in Tab.allCases.enumerated() { + let tabs: [Tab] = [ + .home, + .search, + .notification, + .me + ] + for (i, tab) in tabs.enumerated() { let title = L10n.Common.Controls.Keyboard.Common.switchToTab(tab.title) let input = String(i + 1) let command = UIKeyCommand( @@ -584,7 +695,7 @@ extension MainTabBarController { let previousTab = Tab(rawValue: selectedIndex) selectedIndex = index if let tab = Tab(rawValue: index) { - currentTab.value = tab + currentTab = tab } if let previousTab = previousTab { diff --git a/Mastodon/Scene/Root/RootSplitViewController.swift b/Mastodon/Scene/Root/RootSplitViewController.swift index d9b18b0b4..f19282936 100644 --- a/Mastodon/Scene/Root/RootSplitViewController.swift +++ b/Mastodon/Scene/Root/RootSplitViewController.swift @@ -208,7 +208,7 @@ extension RootSplitViewController: UISplitViewControllerDelegate { switch proposedTopColumn { case .compact: RootSplitViewController.transform(from: contentSplitViewController.mainTabBarController, to: compactMainTabBarViewController) - compactMainTabBarViewController.currentTab.value = contentSplitViewController.currentSupplementaryTab + compactMainTabBarViewController.currentTab = contentSplitViewController.currentSupplementaryTab default: assertionFailure() @@ -231,11 +231,11 @@ extension RootSplitViewController: UISplitViewControllerDelegate { RootSplitViewController.transform(from: compactMainTabBarViewController, to: contentSplitViewController.mainTabBarController) - let tab = compactMainTabBarViewController.currentTab.value + let tab = compactMainTabBarViewController.currentTab if tab == .search { contentSplitViewController.currentSupplementaryTab = .home } else { - contentSplitViewController.currentSupplementaryTab = compactMainTabBarViewController.currentTab.value + contentSplitViewController.currentSupplementaryTab = compactMainTabBarViewController.currentTab } return proposedDisplayMode diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift index 7ac0f6e54..c7cf3d49d 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewController.swift @@ -154,10 +154,9 @@ extension SidebarViewController { coordinator.animate { context in self.collectionView.collectionViewLayout.invalidateLayout() - } completion: { [weak self] context in -// guard let self = self else { return } + } completion: { context in + // do nothing } - } } diff --git a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift index 3cc277dc6..a6698d6c2 100644 --- a/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift +++ b/Mastodon/Scene/Root/Sidebar/SidebarViewModel.swift @@ -22,7 +22,8 @@ final class SidebarViewModel { let context: AppContext @Published private var isSidebarDataSourceReady = false @Published private var isAvatarButtonDataReady = false - + @Published var currentTab: MainTabBarController.Tab = .home + // output var diffableDataSource: UICollectionViewDiffableDataSource? var secondaryDiffableDataSource: UICollectionViewDiffableDataSource? @@ -86,35 +87,55 @@ extension SidebarViewModel { } }() cell.item = SidebarListContentView.Item( + isActive: false, title: item.title, - image: item.sidebarImage, + image: item.image, + activeImage: item.selectedImage, imageURL: imageURL ) cell.setNeedsUpdateConfiguration() cell.isAccessibilityElement = true cell.accessibilityLabel = item.title + self.$currentTab + .receive(on: DispatchQueue.main) + .sink { [weak cell] currentTab in + guard let cell = cell else { return } + cell.item?.isActive = currentTab == item + cell.setNeedsUpdateConfiguration() + } + .store(in: &cell.disposeBag) + switch item { case .notification: - Publishers.CombineLatest( + Publishers.CombineLatest3( self.context.authenticationService.activeMastodonAuthentication, - self.context.notificationService.unreadNotificationCountDidUpdate + self.context.notificationService.unreadNotificationCountDidUpdate, + self.$currentTab ) .receive(on: DispatchQueue.main) - .sink { [weak cell] authentication, _ in + .sink { [weak cell] authentication, _, currentTab in guard let cell = cell else { return } let hasUnreadPushNotification: Bool = authentication.flatMap { authentication in let count = UserDefaults.shared.getNotificationCountWithAccessToken(accessToken: authentication.userAccessToken) return count > 0 } ?? false - let image = hasUnreadPushNotification ? UIImage(systemName: "bell.badge")! : UIImage(systemName: "bell")! - cell._contentView?.imageView.image = image + let image: UIImage = { + if currentTab == .notification { + return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadgeFill.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bellFill.image.withRenderingMode(.alwaysTemplate) + } else { + return hasUnreadPushNotification ? Asset.ObjectsAndTools.bellBadge.image.withRenderingMode(.alwaysTemplate) : Asset.ObjectsAndTools.bell.image.withRenderingMode(.alwaysTemplate) + } + }() + cell.item?.image = image + cell.item?.activeImage = image + cell.setNeedsUpdateConfiguration() } .store(in: &cell.disposeBag) case .me: guard let authentication = self.context.authenticationService.activeMastodonAuthentication.value else { break } - let currentUserDisplayName = authentication.user.displayNameWithFallback ?? "no user" + let currentUserDisplayName = authentication.user.displayNameWithFallback cell.accessibilityHint = L10n.Scene.AccountList.tabBarHint(currentUserDisplayName) default: break @@ -122,7 +143,7 @@ extension SidebarViewModel { } let cellRegistration = UICollectionView.CellRegistration { [weak self] cell, indexPath, item in - guard let self = self else { return } + guard let _ = self else { return } cell.item = item cell.setNeedsUpdateConfiguration() cell.isAccessibilityElement = true @@ -140,15 +161,19 @@ extension SidebarViewModel { return collectionView.dequeueConfiguredReusableCell(using: tabCellRegistration, for: indexPath, item: tab) case .setting: let item = SidebarListContentView.Item( + isActive: false, title: L10n.Common.Controls.Actions.settings, - image: UIImage(systemName: "gear")!, + image: Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate), + activeImage: Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate), imageURL: nil ) return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item) case .compose: let item = SidebarListContentView.Item( + isActive: false, title: L10n.Common.Controls.Actions.compose, - image: UIImage(systemName: "square.and.pencil")!, + image: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate), + activeImage: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate), imageURL: nil ) return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item) @@ -192,15 +217,15 @@ extension SidebarViewModel { } let item = SidebarListContentView.Item( + isActive: false, title: L10n.Common.Controls.Actions.compose, - image: UIImage(systemName: "square.and.pencil")!, + image: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate), + activeImage: Asset.ObjectsAndTools.squareAndPencil.image.withRenderingMode(.alwaysTemplate), imageURL: nil ) return collectionView.dequeueConfiguredReusableCell(using: cellRegistration, for: indexPath, item: item) } -// _secondaryDiffableDataSource.supplementaryViewProvider = { collectionView, elementKind, indexPath in -// return nil -// } + secondaryDiffableDataSource = _secondaryDiffableDataSource var secondarySnapshot = NSDiffableDataSourceSnapshot() diff --git a/Mastodon/Scene/Root/Sidebar/View/SidebarListContentView.swift b/Mastodon/Scene/Root/Sidebar/View/SidebarListContentView.swift index d6ae40e17..794563eaf 100644 --- a/Mastodon/Scene/Root/Sidebar/View/SidebarListContentView.swift +++ b/Mastodon/Scene/Root/Sidebar/View/SidebarListContentView.swift @@ -93,12 +93,14 @@ extension SidebarListContentView { // configure model imageView.isHidden = item.imageURL != nil avatarButton.isHidden = item.imageURL == nil - imageView.image = item.image.withRenderingMode(.alwaysTemplate) + imageView.image = item.isActive ? item.activeImage.withRenderingMode(.alwaysTemplate) : item.image.withRenderingMode(.alwaysTemplate) avatarButton.avatarImageView.setImage( url: item.imageURL, placeholder: avatarButton.avatarImageView.image ?? .placeholder(color: .systemFill), // reuse to avoid blink scaleToSize: nil ) + avatarButton.borderWidth = item.isActive ? 2 : 0 + avatarButton.setNeedsLayout() } } @@ -107,25 +109,32 @@ extension SidebarListContentView { // state var isSelected: Bool = false var isHighlighted: Bool = false + var isActive: Bool // model let title: String - let image: UIImage + var image: UIImage + var activeImage: UIImage let imageURL: URL? + static func == (lhs: SidebarListContentView.Item, rhs: SidebarListContentView.Item) -> Bool { return lhs.isSelected == rhs.isSelected && lhs.isHighlighted == rhs.isHighlighted + && lhs.isActive == rhs.isActive && lhs.title == rhs.title && lhs.image == rhs.image + && lhs.activeImage == rhs.activeImage && lhs.imageURL == rhs.imageURL } func hash(into hasher: inout Hasher) { hasher.combine(isSelected) hasher.combine(isHighlighted) + hasher.combine(isActive) hasher.combine(title) hasher.combine(image) + hasher.combine(activeImage) imageURL.flatMap { hasher.combine($0) } } } diff --git a/Mastodon/Scene/Settings/SettingsViewController.swift b/Mastodon/Scene/Settings/SettingsViewController.swift index 4cf20cd09..8455ac7d9 100644 --- a/Mastodon/Scene/Settings/SettingsViewController.swift +++ b/Mastodon/Scene/Settings/SettingsViewController.swift @@ -448,7 +448,7 @@ extension SettingsViewController: SettingsAppearanceTableViewCellDelegate { guard let dataSource = viewModel.dataSource else { return } guard let indexPath = tableView.indexPath(for: cell) else { return } let item = dataSource.itemIdentifier(for: indexPath) - guard case let .appearance(record) = item else { return } + guard case .appearance = item else { return } Task { @MainActor in switch appearanceMode { diff --git a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift index aac23285b..f4ad467da 100644 --- a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift +++ b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift @@ -10,7 +10,41 @@ import UIKit // Make status bar style adaptive for child view controller // SeeAlso: `modalPresentationCapturesStatusBarAppearance` class AdaptiveStatusBarStyleNavigationController: UINavigationController { + + private lazy var fullWidthBackGestureRecognizer = UIPanGestureRecognizer() + override var childForStatusBarStyle: UIViewController? { visibleViewController } } + +// ref: https://stackoverflow.com/a/60598558/3797903 +extension AdaptiveStatusBarStyleNavigationController { + + override func viewDidLoad() { + super.viewDidLoad() + setupFullWidthBackGesture() + } + + private func setupFullWidthBackGesture() { + // The trick here is to wire up our full-width `fullWidthBackGestureRecognizer` to execute the same handler as + // the system `interactivePopGestureRecognizer`. That's done by assigning the same "targets" (effectively + // object and selector) of the system one to our gesture recognizer. + guard let interactivePopGestureRecognizer = interactivePopGestureRecognizer, + let targets = interactivePopGestureRecognizer.value(forKey: "targets") + else { return } + + fullWidthBackGestureRecognizer.setValue(targets, forKey: "targets") + fullWidthBackGestureRecognizer.delegate = self + view.addGestureRecognizer(fullWidthBackGestureRecognizer) + } +} + +// MARK: - UIGestureRecognizerDelegate +extension AdaptiveStatusBarStyleNavigationController: UIGestureRecognizerDelegate { + func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + let isSystemSwipeToBackEnabled = interactivePopGestureRecognizer?.isEnabled == true + let isThereStackedViewControllers = viewControllers.count > 1 + return isSystemSwipeToBackEnabled && isThereStackedViewControllers + } +} diff --git a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift index f730e0b8b..1b2d62211 100644 --- a/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift +++ b/Mastodon/Scene/Transition/MediaPreview/MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift @@ -255,6 +255,8 @@ extension MediaHostToMediaPreviewViewControllerAnimatedTransitioning { rect.size.height -= offset return rect }() + + // FIXME: let maskLayerToFinalPath = maskLayerToFinalRect.flatMap { UIBezierPath(rect: $0) }?.cgPath if let maskLayerToPath = maskLayerToPath { diff --git a/Mastodon/Service/APIService/APIService+Thread.swift b/Mastodon/Service/APIService/APIService+Thread.swift index 782da5886..f6c36e5b6 100644 --- a/Mastodon/Service/APIService/APIService+Thread.swift +++ b/Mastodon/Service/APIService/APIService+Thread.swift @@ -34,7 +34,7 @@ extension APIService { let value = response.value.ancestors + response.value.descendants for entity in value { - Persistence.Status.createOrMerge( + _ = Persistence.Status.createOrMerge( in: managedObjectContext, context: Persistence.Status.PersistContext( domain: domain, diff --git a/Mastodon/Service/InstanceService.swift b/Mastodon/Service/InstanceService.swift index 4fb6309fd..03b8dfd4e 100644 --- a/Mastodon/Service/InstanceService.swift +++ b/Mastodon/Service/InstanceService.swift @@ -95,7 +95,7 @@ extension InstanceService { self.logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [Instance] update instance for domain: \(domain)") } } receiveValue: { [weak self] response in - guard let self = self else { return } + guard let _ = self else { return } // do nothing } .store(in: &disposeBag) diff --git a/MastodonIntent/Info.plist b/MastodonIntent/Info.plist index d08d9c217..3f1630945 100644 --- a/MastodonIntent/Info.plist +++ b/MastodonIntent/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 NSExtension NSExtensionAttributes diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Contents.json new file mode 100644 index 000000000..33c521feb --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Share iOS.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Share iOS.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Share iOS.pdf new file mode 100644 index 000000000..99e7c6724 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/Arrow/square.and.arrow.up.imageset/Share iOS.pdf @@ -0,0 +1,110 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 5.004150 3.928345 cm +0.000000 0.000000 0.000000 scn +16.750000 11.071655 m +17.129696 11.071655 17.443491 10.789501 17.493153 10.423426 c +17.500000 10.321655 l +17.500000 3.320786 l +17.500000 1.587753 16.143545 0.171539 14.434423 0.075930 c +14.250000 0.070786 l +3.250000 0.070786 l +1.516969 0.070786 0.100754 1.427240 0.005145 3.136362 c +0.000000 3.320786 l +0.000000 10.321655 l +0.000000 10.735868 0.335786 11.071655 0.750000 11.071655 c +1.129696 11.071655 1.443491 10.789501 1.493153 10.423426 c +1.500000 10.321655 l +1.500000 3.320786 l +1.500000 2.402613 2.207110 1.649591 3.106473 1.576586 c +3.250000 1.570786 l +14.250000 1.570786 l +15.168174 1.570786 15.921191 2.277895 15.994198 3.177258 c +16.000000 3.320786 l +16.000000 10.321655 l +16.000000 10.735868 16.335787 11.071655 16.750000 11.071655 c +h +3.215397 14.855352 m +8.211636 19.851965 l +8.477744 20.118093 8.894129 20.142456 9.187749 19.924934 c +9.271878 19.852423 l +14.276731 14.855809 l +14.569866 14.563158 14.570257 14.088284 14.277605 13.795150 c +14.011558 13.528664 13.594913 13.504115 13.301123 13.721727 c +13.216944 13.794276 l +9.493999 17.510654 l +9.494885 5.816710 l +9.494885 5.437014 9.212732 5.123218 8.846657 5.073555 c +8.744885 5.066710 l +8.365190 5.066710 8.051395 5.348864 8.001733 5.714939 c +7.994885 5.816710 l +7.993999 17.513655 l +4.276096 13.794732 l +4.009840 13.528456 3.593178 13.504234 3.299558 13.722077 c +3.215437 13.794693 l +2.949160 14.060949 2.924938 14.477612 3.142782 14.771232 c +3.215397 14.855352 l +8.211636 19.851965 l +3.215397 14.855352 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 1600 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001690 00000 n +0000001713 00000 n +0000001886 00000 n +0000001960 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +2019 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/Contents.json new file mode 100644 index 000000000..956d7c99c --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bell.badge.fill.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/bell.badge.fill.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/bell.badge.fill.pdf new file mode 100644 index 000000000..10b05f319 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.fill.imageset/bell.badge.fill.pdf @@ -0,0 +1,94 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 4.000000 3.251190 cm +0.000000 0.000000 0.000000 scn +17.228973 14.106000 m +17.604315 14.106000 17.967243 14.159944 18.310644 14.260609 c +18.330521 14.022223 18.340664 13.781026 18.340664 13.537420 c +18.340664 9.025727 l +19.917404 5.460056 l +19.978443 5.322020 20.010000 5.172432 20.010000 5.021130 c +20.010000 4.429121 19.537165 3.949203 18.953897 3.949203 c +1.056364 3.949203 l +0.907638 3.949203 0.760588 3.981087 0.624843 4.042767 c +0.092485 4.284660 -0.145878 4.918783 0.092444 5.459118 c +1.665367 9.025314 l +1.665486 13.551995 l +1.670396 13.833986 l +1.824999 18.382032 5.507209 22.000000 10.003014 22.000000 c +11.607554 22.000000 13.106230 21.539965 14.378001 20.742750 c +13.732699 20.037863 13.338069 19.093309 13.338069 18.055204 c +13.338069 15.874119 15.080086 14.106000 17.228973 14.106000 c +h +13.291688 2.819208 m +13.026393 1.219061 11.654965 0.000000 10.003014 0.000000 c +8.351062 0.000000 6.979633 1.219061 6.714338 2.819208 c +13.291688 2.819208 l +h +17.228973 15.234344 m +18.763893 15.234344 20.008190 16.497286 20.008190 18.055204 c +20.008190 19.613121 18.763893 20.876064 17.228973 20.876064 c +15.694054 20.876064 14.449756 19.613121 14.449756 18.055204 c +14.449756 16.497286 15.694054 15.234344 17.228973 15.234344 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 1305 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001395 00000 n +0000001418 00000 n +0000001591 00000 n +0000001665 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1724 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/Contents.json new file mode 100644 index 000000000..7e5adf71d --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bell.badge.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/bell.badge.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/bell.badge.pdf new file mode 100644 index 000000000..0aa1ebbd9 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.badge.imageset/bell.badge.pdf @@ -0,0 +1,112 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 4.000000 3.000000 cm +0.000000 0.000000 0.000000 scn +9.991263 22.000000 m +11.600367 22.000000 13.104079 21.540958 14.379686 20.742632 c +13.999659 20.330532 13.705750 19.835861 13.527027 19.288073 c +12.501425 19.935305 11.289410 20.308149 9.991263 20.308149 c +6.295337 20.308149 3.312736 17.291861 3.312205 13.540749 c +3.312205 8.567127 l +1.816118 5.077236 l +18.175934 5.077236 l +16.670322 8.566052 l +16.670446 13.526248 l +16.666271 13.780252 l +16.662128 13.902481 16.654818 14.023849 16.644423 14.144276 c +16.834492 14.115398 17.029049 14.100430 17.227058 14.100430 c +17.602913 14.100430 17.966335 14.154360 18.310204 14.254990 c +18.322084 14.112284 18.330519 13.968523 18.335421 13.823792 c +18.340088 13.540749 l +18.340088 8.919773 l +19.876272 5.360107 l +19.953144 5.181980 19.992825 4.989672 19.992825 4.795261 c +19.992825 4.016609 19.369843 3.385387 18.601355 3.385387 c +13.330793 3.383699 l +13.330793 1.514933 11.835634 -0.000002 9.991263 -0.000002 c +8.212763 -0.000002 6.758977 1.408655 6.657403 3.184881 c +6.651230 3.386263 l +1.391824 3.385387 l +1.201094 3.385387 1.012400 3.425116 0.837460 3.502110 c +0.132594 3.812326 -0.190615 4.642769 0.115552 5.356956 c +1.642440 8.918699 l +1.642440 13.540869 l +1.643104 18.227058 5.373904 22.000000 9.991263 22.000000 c +h +11.660524 3.386263 m +8.321499 3.383699 l +8.321499 2.449318 9.069077 1.691849 9.991263 1.691849 c +10.859203 1.691849 11.572474 2.362822 11.653385 3.220762 c +11.660524 3.386263 l +h +14.488358 18.551571 m +14.594155 19.146286 14.884010 19.676186 15.296021 20.078548 c +15.796463 20.567268 16.477119 20.867832 17.227058 20.867832 c +18.764036 20.867832 20.010000 19.605387 20.010000 18.048080 c +20.010000 16.815081 19.228939 15.766922 18.140787 15.383841 c +17.854582 15.283082 17.547131 15.228331 17.227058 15.228331 c +16.950932 15.228331 16.684196 15.269077 16.432392 15.344961 c +15.282606 15.691461 14.444118 16.770555 14.444118 18.048080 c +14.444118 18.219936 14.459294 18.388199 14.488358 18.551571 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 2038 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000002128 00000 n +0000002151 00000 n +0000002324 00000 n +0000002398 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +2457 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/Contents.json new file mode 100644 index 000000000..eea5ce48f --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bell.fill.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/bell.fill.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/bell.fill.pdf new file mode 100644 index 000000000..b738813f8 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.fill.imageset/bell.fill.pdf @@ -0,0 +1,88 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 3.994385 2.997498 cm +0.000000 0.000000 0.000000 scn +13.471207 3.000130 m +13.228097 1.303843 11.769090 0.000013 10.005556 0.000013 c +8.242023 0.000013 6.783014 1.303843 6.539904 3.000130 c +13.471207 3.000130 l +h +10.005556 22.002502 m +14.615297 22.002502 18.368101 18.333513 18.503042 13.756456 c +18.503042 13.501259 l +18.506800 13.501259 l +18.506556 9.389503 l +19.920570 5.745182 l +19.958755 5.646759 19.984545 5.544180 19.997494 5.439810 c +20.007233 5.282207 l +20.007233 4.619465 19.503553 4.074364 18.858105 4.008816 c +18.727232 4.002207 l +1.280344 4.002207 l +1.121637 4.002207 0.964313 4.031721 0.816398 4.089247 c +0.198722 4.329462 -0.126749 4.996468 0.046107 5.621784 c +0.087384 5.746153 l +1.503556 9.390502 l +1.504312 13.501259 l +1.504312 18.196365 5.310449 22.002502 10.005556 22.002502 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 870 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000960 00000 n +0000000982 00000 n +0000001155 00000 n +0000001229 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1288 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/Contents.json new file mode 100644 index 000000000..da621b2a4 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "bell.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/bell.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/bell.pdf new file mode 100644 index 000000000..52a4bea08 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/bell.imageset/bell.pdf @@ -0,0 +1,106 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 3.994385 2.997498 cm +0.000000 0.000000 0.000000 scn +10.005556 22.002502 m +14.615297 22.002502 18.368101 18.333513 18.503042 13.756456 c +18.506800 13.501259 l +18.506556 8.889502 l +19.920570 5.245478 l +19.958755 5.147055 19.984545 5.044476 19.997494 4.940105 c +20.007233 4.782503 l +20.007233 4.119761 19.503553 3.574659 18.858105 3.509111 c +18.727232 3.502502 l +13.506981 3.501438 l +13.506981 1.567654 11.939340 0.000013 10.005556 0.000013 c +8.136232 0.000013 6.609047 1.464890 6.509312 3.309326 c +6.504000 3.503502 l +1.280344 3.502502 l +1.121637 3.502502 0.964313 3.532017 0.816398 3.589542 c +0.198722 3.829758 -0.126749 4.496763 0.046107 5.122080 c +0.087384 5.246449 l +1.503556 8.890503 l +1.504312 13.501259 l +1.504312 18.196365 5.310449 22.002502 10.005556 22.002502 c +h +12.001492 3.352070 m +12.006001 3.503502 l +8.004131 3.501438 l +8.004131 2.396082 8.900200 1.500013 10.005556 1.500013 c +11.060669 1.500013 11.925088 2.316473 12.001492 3.352070 c +h +10.005556 20.502502 m +6.219432 20.502502 3.135237 17.497185 3.008372 13.741951 c +3.004312 13.501259 l +3.004312 8.749136 l +3.004312 8.687140 2.996625 8.625507 2.981514 8.565626 c +2.953312 8.477293 l +1.601556 5.003502 l +18.405556 5.003502 l +17.057579 8.477861 l +17.035206 8.535532 17.020094 8.595635 17.012506 8.656790 c +17.006800 8.749136 l +17.006800 13.501259 l +17.006800 17.367939 13.872236 20.502502 10.005556 20.502502 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 1451 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001541 00000 n +0000001564 00000 n +0000001737 00000 n +0000001811 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1870 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/Contents.json new file mode 100644 index 000000000..8dfa77c79 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "gear.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/gear.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/gear.pdf new file mode 100644 index 000000000..d0e5607b9 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/gear.imageset/gear.pdf @@ -0,0 +1,155 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 4.639893 4.163849 cm +0.000000 0.000000 0.000000 scn +9.372525 19.586090 m +10.106503 19.577631 10.837610 19.492828 11.554037 19.333052 c +11.866778 19.263306 12.100667 19.002579 12.136167 18.684128 c +12.306372 17.157282 l +12.383412 16.456230 12.975316 15.925249 13.680974 15.924509 c +13.870646 15.924213 14.058271 15.963713 14.233541 16.041258 c +15.634164 16.656530 l +15.925470 16.784498 16.265816 16.714733 16.483282 16.482475 c +17.495462 15.401449 18.249289 14.104940 18.688040 12.690507 c +18.782648 12.385511 18.673761 12.054057 18.416712 11.864587 c +17.175230 10.949497 l +16.821091 10.689301 16.611935 10.276085 16.611935 9.836634 c +16.611935 9.397182 16.821091 8.983968 17.176010 8.723198 c +18.418562 7.807791 l +18.675699 7.618353 18.784660 7.286852 18.690054 6.981801 c +18.251465 5.567602 17.498068 4.271195 16.486473 3.189995 c +16.269207 2.957779 15.929114 2.887827 15.637836 3.015442 c +14.231503 3.631588 l +13.829185 3.807648 13.367112 3.781857 12.986887 3.562117 c +12.606662 3.342377 12.353621 2.954891 12.305302 2.518358 c +12.136227 0.991678 l +12.101363 0.676876 11.872503 0.417910 11.564378 0.344601 c +10.115929 -0.000013 8.606833 -0.000013 7.158383 0.344601 c +6.850258 0.417910 6.621398 0.676876 6.586535 0.991678 c +6.417712 2.516102 l +6.368124 2.951803 6.114693 3.338112 5.734776 3.557108 c +5.354860 3.776103 4.893555 3.801792 4.492552 3.626715 c +3.085926 3.010441 l +2.794572 2.882792 2.454386 2.952816 2.237134 3.185158 c +1.224976 4.267610 0.471545 5.565555 0.033552 6.981297 c +-0.060786 7.286231 0.048213 7.617466 0.305198 7.806790 c +1.548530 8.722771 l +1.902669 8.982967 2.111826 9.396182 2.111826 9.835633 c +2.111826 10.275084 1.902669 10.688300 1.548066 10.948837 c +0.305513 11.863244 l +0.048147 12.052642 -0.060952 12.384308 0.033719 12.689507 c +0.472470 14.103941 1.226297 15.400448 2.238477 16.481474 c +2.455943 16.713732 2.796290 16.783497 3.087596 16.655531 c +4.487972 16.040365 l +4.890913 15.863533 5.354152 15.890244 5.736122 16.113400 c +6.116442 16.334003 6.369638 16.721867 6.418519 17.158447 c +6.588595 18.684128 l +6.624113 19.002741 6.858214 19.263550 7.171155 19.333147 c +7.888429 19.492670 8.620303 19.577436 9.372525 19.586090 c +h +9.372712 18.086191 m +8.918673 18.080845 8.465910 18.041662 8.018175 17.969074 c +7.909245 16.991905 l +7.807416 16.082413 7.280385 15.275068 6.490771 14.817059 c +5.696323 14.352917 4.727715 14.297064 3.884934 14.666923 c +2.986644 15.061529 l +2.414711 14.367364 1.959492 13.584736 1.638873 12.744408 c +2.436671 12.157299 l +3.175481 11.614474 3.611826 10.752420 3.611826 9.835633 c +3.611826 8.918846 3.175481 8.056792 2.437450 7.514541 c +1.638397 6.925866 l +1.958737 6.084057 2.414029 5.299965 2.986352 4.604462 c +3.891485 5.001020 l +4.729578 5.366932 5.691594 5.313361 6.483880 4.856663 c +7.276166 4.399964 7.804679 3.594347 7.908344 2.683468 c +8.017305 1.699598 l +8.906950 1.548321 9.815811 1.548321 10.705456 1.699598 c +10.814412 2.683426 l +10.915205 3.594033 11.443104 4.402411 12.236333 4.860834 c +13.029562 5.319258 13.993543 5.373064 14.833156 5.005638 c +15.737573 4.609392 l +16.309378 5.303812 16.764484 6.086632 17.085032 6.927112 c +16.287088 7.514968 l +15.548278 8.057793 15.111936 8.919847 15.111936 9.836634 c +15.111936 10.753421 15.548280 11.615475 16.286161 12.157617 c +17.083044 12.744996 l +16.762415 13.585482 16.307142 14.368252 15.735116 15.062530 c +14.838643 14.668724 l +14.473309 14.507083 14.078127 14.423886 13.679017 14.424510 c +12.209332 14.426050 10.975889 15.532539 10.815476 16.992264 c +10.706551 17.969393 l +10.261019 18.041893 9.812987 18.080971 9.372712 18.086191 c +h +9.360047 13.586140 m +11.431115 13.586140 13.110047 11.907207 13.110047 9.836140 c +13.110047 7.765072 11.431115 6.086140 9.360047 6.086140 c +7.288980 6.086140 5.610047 7.765072 5.610047 9.836140 c +5.610047 11.907207 7.288980 13.586140 9.360047 13.586140 c +h +9.360047 12.086140 m +8.117407 12.086140 7.110047 11.078780 7.110047 9.836140 c +7.110047 8.593499 8.117407 7.586140 9.360047 7.586140 c +10.602688 7.586140 11.610047 8.593499 11.610047 9.836140 c +11.610047 11.078780 10.602688 12.086140 9.360047 12.086140 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 4141 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000004231 00000 n +0000004254 00000 n +0000004427 00000 n +0000004501 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +4560 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Contents.json new file mode 100644 index 000000000..b12998cbd --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Home-fill.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Home-fill.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Home-fill.pdf new file mode 100644 index 000000000..e8e156e31 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.fill.imageset/Home-fill.pdf @@ -0,0 +1,85 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 4.000000 2.835022 cm +0.000000 0.000000 0.000000 scn +8.592125 21.667089 m +9.414732 22.326954 10.585270 22.326952 11.407875 21.667089 c +19.157869 15.450343 l +19.690231 15.023304 19.999994 14.377716 19.999994 13.695241 c +19.999994 2.414970 l +19.999994 1.172331 18.992638 0.164970 17.749996 0.164970 c +15.250000 0.164970 l +14.007360 0.164970 13.000000 1.172327 13.000000 2.414968 c +13.000000 8.914963 l +13.000000 9.329177 12.664214 9.664963 12.250000 9.664963 c +7.750000 9.664963 l +7.335785 9.664963 7.000000 9.329177 7.000000 8.914964 c +7.000000 2.414970 l +7.000000 1.172331 5.992641 0.164970 4.750000 0.164970 c +2.250000 0.164970 l +1.007360 0.164970 0.000000 1.172327 0.000000 2.414968 c +0.000000 13.695240 l +0.000000 14.377715 0.309763 15.023304 0.842125 15.450343 c +8.592125 21.667089 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 862 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000952 00000 n +0000000974 00000 n +0000001147 00000 n +0000001221 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1280 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Contents.json new file mode 100644 index 000000000..968281c21 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Home.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Home.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Home.pdf new file mode 100644 index 000000000..1b5772ddd --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/house.imageset/Home.pdf @@ -0,0 +1,105 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 4.000000 2.834961 cm +0.000000 0.000000 0.000000 scn +8.591907 21.668686 m +9.414594 22.328781 10.585405 22.328781 11.408092 21.668686 c +19.158089 15.450356 l +19.690319 15.023312 19.999994 14.377806 19.999994 13.695429 c +19.999994 2.415045 l +19.999994 1.172405 18.992638 0.165045 17.749996 0.165045 c +14.750000 0.165045 l +13.507360 0.165045 12.500000 1.172403 12.500000 2.415045 c +12.500000 8.415037 l +12.500000 8.829250 12.164213 9.165037 11.750000 9.165037 c +8.250000 9.165037 l +7.835786 9.165037 7.500000 8.829250 7.500000 8.415037 c +7.500000 2.415045 l +7.500000 1.172403 6.492640 0.165045 5.250000 0.165045 c +2.250000 0.165045 l +1.007360 0.165045 0.000000 1.172401 0.000000 2.415043 c +0.000000 13.695428 l +0.000000 14.377805 0.309674 15.023312 0.841907 15.450356 c +8.591907 21.668686 l +h +10.469363 20.498734 m +10.195135 20.718765 9.804865 20.718765 9.530635 20.498734 c +1.780635 14.280403 l +1.603225 14.138056 1.500000 13.922887 1.500000 13.695428 c +1.500000 2.415043 l +1.500000 2.000832 1.835786 1.665045 2.250000 1.665045 c +5.250000 1.665045 l +5.664214 1.665045 6.000000 2.000832 6.000000 2.415045 c +6.000000 8.415037 l +6.000000 9.657678 7.007360 10.665037 8.250000 10.665037 c +11.750000 10.665037 l +12.992640 10.665037 14.000000 9.657678 14.000000 8.415037 c +14.000000 2.415045 l +14.000000 2.000832 14.335787 1.665045 14.750000 1.665045 c +17.749996 1.665045 l +18.164207 1.665045 18.499994 2.000830 18.499994 2.415045 c +18.499994 13.695429 l +18.499994 13.922888 18.396770 14.138056 18.219358 14.280403 c +10.469363 20.498734 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 1604 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001694 00000 n +0000001717 00000 n +0000001890 00000 n +0000001964 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +2023 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Contents.json new file mode 100644 index 000000000..6986c762a --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Search-Fill.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Search-Fill.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Search-Fill.pdf new file mode 100644 index 000000000..26e5a4576 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.fill.imageset/Search-Fill.pdf @@ -0,0 +1,83 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 2.000000 1.855835 cm +0.000000 0.000000 0.000000 scn +9.500000 24.144165 m +14.746705 24.144165 19.000000 19.890869 19.000000 14.644165 c +19.000000 12.562231 18.330292 10.636717 17.194551 9.071299 c +23.560659 2.704824 l +24.146446 2.119038 24.146446 1.169292 23.560659 0.583506 c +23.011484 0.034330 22.142424 0.000008 21.553263 0.480536 c +21.439341 0.583506 l +15.072866 6.949614 l +13.507448 5.813873 11.581934 5.144165 9.500000 5.144165 c +4.253295 5.144165 0.000000 9.397460 0.000000 14.644165 c +0.000000 19.890869 4.253295 24.144165 9.500000 24.144165 c +h +9.500000 21.144165 m +5.910149 21.144165 3.000000 18.234016 3.000000 14.644165 c +3.000000 11.054314 5.910149 8.144165 9.500000 8.144165 c +13.089851 8.144165 16.000000 11.054314 16.000000 14.644165 c +16.000000 18.234016 13.089851 21.144165 9.500000 21.144165 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 887 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000977 00000 n +0000000999 00000 n +0000001172 00000 n +0000001246 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1305 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Contents.json new file mode 100644 index 000000000..e4ab2267b --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "Search.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Search.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Search.pdf new file mode 100644 index 000000000..7bd1758c7 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/magnifyingglass.imageset/Search.pdf @@ -0,0 +1,83 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 2.750000 2.679199 cm +0.000000 0.000000 0.000000 scn +8.750000 22.570801 m +13.582491 22.570801 17.500000 18.653292 17.500000 13.820801 c +17.500000 11.674633 16.727327 9.708933 15.444990 8.186705 c +22.280331 1.351131 l +22.573223 1.058239 22.573223 0.583363 22.280331 0.290470 c +22.014065 0.024204 21.597401 -0.000004 21.303789 0.217852 c +21.219669 0.290470 l +14.384096 7.125811 l +12.861868 5.843473 10.896168 5.070801 8.750000 5.070801 c +3.917509 5.070801 0.000000 8.988310 0.000000 13.820801 c +0.000000 18.653292 3.917509 22.570801 8.750000 22.570801 c +h +8.750000 21.070801 m +4.745935 21.070801 1.500000 17.824865 1.500000 13.820801 c +1.500000 9.816736 4.745935 6.570801 8.750000 6.570801 c +12.754065 6.570801 16.000000 9.816736 16.000000 13.820801 c +16.000000 17.824865 12.754065 21.070801 8.750000 21.070801 c +h +f +n +Q + +endstream +endobj + +3 0 obj + 885 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 28.000000 28.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000000975 00000 n +0000000997 00000 n +0000001170 00000 n +0000001244 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1303 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/Contents.json b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/Contents.json new file mode 100644 index 000000000..18bb2201a --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "square.and.pencil.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true + } +} diff --git a/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/square.and.pencil.pdf b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/square.and.pencil.pdf new file mode 100644 index 000000000..8cb4a15c9 --- /dev/null +++ b/MastodonSDK/Sources/MastodonAsset/Assets.xcassets/ObjectsAndTools/square.and.pencil.imageset/square.and.pencil.pdf @@ -0,0 +1,93 @@ +%PDF-1.7 + +1 0 obj + << >> +endobj + +2 0 obj + << /Length 3 0 R >> +stream +/DeviceRGB CS +/DeviceRGB cs +q +1.000000 0.000000 -0.000000 1.000000 3.000000 2.926788 cm +0.000000 0.000000 0.000000 scn +18.780287 17.792883 m +19.073179 18.085777 19.073177 18.560650 18.780285 18.853542 c +18.487391 19.146435 18.012516 19.146435 17.719624 18.853540 c +7.719669 8.853540 l +7.250000 7.323212 l +8.780332 7.792883 l +18.780287 17.792883 l +h +3.249999 18.073212 m +1.455072 18.073212 0.000000 16.618137 0.000000 14.823212 c +0.000000 3.323212 l +0.000000 1.528286 1.455075 0.073212 3.250000 0.073212 c +14.750000 0.073212 l +16.544926 0.073212 18.000000 1.528286 18.000000 3.323212 c +18.000000 11.323212 l +18.000000 11.737425 17.664213 12.073212 17.250000 12.073212 c +16.835787 12.073212 16.500000 11.737425 16.500000 11.323212 c +16.500000 3.323212 l +16.500000 2.356712 15.716498 1.573212 14.750000 1.573212 c +3.250000 1.573212 l +2.283502 1.573212 1.500000 2.356712 1.500000 3.323212 c +1.500000 14.823212 l +1.500000 15.789711 2.283501 16.573212 3.249999 16.573212 c +11.249994 16.573212 l +11.664207 16.573212 11.999994 16.908998 11.999994 17.323212 c +11.999994 17.737425 11.664207 18.073212 11.249994 18.073212 c +3.249999 18.073212 l +h +f +n +Q + +endstream +endobj + +3 0 obj + 1142 +endobj + +4 0 obj + << /Annots [] + /Type /Page + /MediaBox [ 0.000000 0.000000 24.000000 24.000000 ] + /Resources 1 0 R + /Contents 2 0 R + /Parent 5 0 R + >> +endobj + +5 0 obj + << /Kids [ 4 0 R ] + /Count 1 + /Type /Pages + >> +endobj + +6 0 obj + << /Pages 5 0 R + /Type /Catalog + >> +endobj + +xref +0 7 +0000000000 65535 f +0000000010 00000 n +0000000034 00000 n +0000001232 00000 n +0000001255 00000 n +0000001428 00000 n +0000001502 00000 n +trailer +<< /ID [ (some) (id) ] + /Root 6 0 R + /Size 7 +>> +startxref +1561 +%%EOF \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift index 3e7fa5c11..b594f9209 100644 --- a/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift +++ b/MastodonSDK/Sources/MastodonAsset/Generated/Assets.swift @@ -24,6 +24,7 @@ public enum Asset { public enum Arrow { public static let `repeat` = ImageAsset(name: "Arrow/repeat") public static let repeatSmall = ImageAsset(name: "Arrow/repeat.small") + public static let squareAndArrowUp = ImageAsset(name: "Arrow/square.and.arrow.up") } public enum Asset { public static let email = ImageAsset(name: "Asset/email") @@ -99,6 +100,16 @@ public enum Asset { public static let faceSmilingAdaptive = ImageAsset(name: "Human/face.smiling.adaptive") } public enum ObjectsAndTools { + public static let bellBadgeFill = ImageAsset(name: "ObjectsAndTools/bell.badge.fill") + public static let bellBadge = ImageAsset(name: "ObjectsAndTools/bell.badge") + public static let bellFill = ImageAsset(name: "ObjectsAndTools/bell.fill") + public static let bell = ImageAsset(name: "ObjectsAndTools/bell") + public static let gear = ImageAsset(name: "ObjectsAndTools/gear") + public static let houseFill = ImageAsset(name: "ObjectsAndTools/house.fill") + public static let house = ImageAsset(name: "ObjectsAndTools/house") + public static let magnifyingglassFill = ImageAsset(name: "ObjectsAndTools/magnifyingglass.fill") + public static let magnifyingglass = ImageAsset(name: "ObjectsAndTools/magnifyingglass") + public static let squareAndPencil = ImageAsset(name: "ObjectsAndTools/square.and.pencil") public static let starFill = ImageAsset(name: "ObjectsAndTools/star.fill") public static let star = ImageAsset(name: "ObjectsAndTools/star") } diff --git a/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift b/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift new file mode 100644 index 000000000..141b723bc --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Extension/UIImage.swift @@ -0,0 +1,18 @@ +// +// UIImage.swift +// +// +// Created by MainasuK on 2022-5-6. +// + +import UIKit + +extension UIImage { + + public func resized(size: CGSize) -> UIImage { + return UIGraphicsImageRenderer(size: size).image { context in + self.draw(in: CGRect(origin: .zero, size: size)) + } + } + +} diff --git a/MastodonTests/Info.plist b/MastodonTests/Info.plist index a1528e2c5..92f442892 100644 --- a/MastodonTests/Info.plist +++ b/MastodonTests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 diff --git a/MastodonUITests/Info.plist b/MastodonUITests/Info.plist index a1528e2c5..92f442892 100644 --- a/MastodonUITests/Info.plist +++ b/MastodonUITests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist index 0029eea56..f074db82b 100644 --- a/NotificationService/Info.plist +++ b/NotificationService/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 NSExtension NSExtensionPointIdentifier diff --git a/ShareActionExtension/Info.plist b/ShareActionExtension/Info.plist index 25fc34294..31c7447fe 100644 --- a/ShareActionExtension/Info.plist +++ b/ShareActionExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.0 + 1.4.1 CFBundleVersion - 121 + 126 NSExtension NSExtensionAttributes diff --git a/update_localization.sh b/update_localization.sh index b234cd933..09cfc21d6 100755 --- a/update_localization.sh +++ b/update_localization.sh @@ -21,7 +21,7 @@ echo "${PODS_ROOT}/SwiftGen/bin/swiftgen" if [[ -f "${PODS_ROOT}/SwiftGen/bin/swiftgen" ]] then "${PODS_ROOT}/SwiftGen/bin/swiftgen" else - echo "Run 'pod install' or update your CocoaPods installation." + echo "Run 'bundle exec pod install' or update your CocoaPods installation." fi #task 4 clean temp file