Merge branch 'release-1.4.6' into feature/package-refactor
# Conflicts: # .arkana.yml # AppShared/Info.plist # Documentation/Setup.md # Gemfile # Gemfile.lock # Mastodon.xcodeproj/project.pbxproj # Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist # Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved # MastodonSDK/Package.swift # MastodonSDK/Sources/MastodonCore/AppSecret.swift # MastodonSDK/Sources/MastodonCore/Service/Notification/NotificationService.swift # Podfile # Podfile.lock
This commit is contained in:
commit
060aec6bcb
|
@ -13,4 +13,5 @@ global_secrets:
|
||||||
# nothing
|
# nothing
|
||||||
environment_secrets:
|
environment_secrets:
|
||||||
# Will lookup for <Key>Debug and <Key>Release env vars (assuming no flavor was declared)
|
# Will lookup for <Key>Debug and <Key>Release env vars (assuming no flavor was declared)
|
||||||
|
# Mastodon Push Notification Endpoint
|
||||||
- NotificationEndpoint
|
- NotificationEndpoint
|
||||||
|
|
|
@ -123,3 +123,6 @@ xcuserdata
|
||||||
# Localization/StringsConvertor/input
|
# Localization/StringsConvertor/input
|
||||||
Localization/StringsConvertor/output
|
Localization/StringsConvertor/output
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
env/**/**
|
||||||
|
!env/.env
|
|
@ -7,8 +7,6 @@
|
||||||
- [CommonOSLog](https://github.com/mainasuk/CommonOSLog)
|
- [CommonOSLog](https://github.com/mainasuk/CommonOSLog)
|
||||||
- [CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)
|
- [CryptoSwift](https://github.com/krzyzanowskim/CryptoSwift)
|
||||||
- [DateToolSwift](https://github.com/MatthewYork/DateTools)
|
- [DateToolSwift](https://github.com/MatthewYork/DateTools)
|
||||||
- [DiffableDataSources](https://github.com/ra1028/DiffableDataSources)
|
|
||||||
- [DifferenceKit](https://github.com/ra1028/DifferenceKit)
|
|
||||||
- [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage)
|
- [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage)
|
||||||
- [FLEX](https://github.com/FLEXTool/FLEX)
|
- [FLEX](https://github.com/FLEXTool/FLEX)
|
||||||
- [FPSIndicator](https://github.com/MainasuK/FPSIndicator)
|
- [FPSIndicator](https://github.com/MainasuK/FPSIndicator)
|
||||||
|
|
|
@ -50,10 +50,11 @@ bundle install
|
||||||
```zsh
|
```zsh
|
||||||
# make a clean build
|
# make a clean build
|
||||||
bundle install
|
bundle install
|
||||||
|
bundle exec pod clean
|
||||||
|
|
||||||
# setup notification endpoint
|
# setup arkana
|
||||||
# please check the `.env.example` to create your's or use the empty example directly
|
# please check the `.env.example` to create your's or use the empty example directly
|
||||||
bundle exec arkana -e `<your-dot-env-file-path>`
|
bundle exec arkana -e ./env/.env
|
||||||
|
|
||||||
# clean pods
|
# clean pods
|
||||||
bundle exec pod clean
|
bundle exec pod clean
|
||||||
|
@ -65,13 +66,14 @@ bundle exec pod install --repo-update
|
||||||
open Mastodon.xcworkspace
|
open Mastodon.xcworkspace
|
||||||
```
|
```
|
||||||
|
|
||||||
The CocoaPods-Key plugin will request the push notification endpoint. You can fufill the empty string and set it later. To setup the push notification. Please check section `Push Notification` below.
|
The Arkana plugin will setup the push notification endpoint. You can use the empty template from `./env/.env` or use your own `.env` file. To setup the push notification. Please check section `Push Notification` below.
|
||||||
|
|
||||||
The app requires the `App Group` capability. To make sure it works for your developer membership. Please check [AppSecret.swift](../MastodonSDK/Sources/MastodonCore/AppSecret.swift) file and set another unique `groupID` and update `App Group` settings.
|
The app requires the `App Group` capability. To make sure it works for your developer membership. Please check [AppSecret.swift](../MastodonSDK/Sources/MastodonCore/AppSecret.swift) file and set another unique `groupID` and update `App Group` settings.
|
||||||
|
|
||||||
#### Push Notification (Optional)
|
#### Push Notification (Optional)
|
||||||
The app is compatible with [toot-relay](https://github.com/DagAgren/toot-relay) APNs. You can set your push notification endpoint via Arkana. There are one endpoint:
|
The app is compatible with [toot-relay](https://github.com/DagAgren/toot-relay) APNs. You can set your push notification endpoint via Arkana. There are two endpoints:
|
||||||
- NotificationEndpoint: (e.g. https://<your-domain>/relay-to/production)
|
- NotificationEndpointDebug: for `DEBUG` usage. e.g. `https://<your.domin>/relay-to/development`
|
||||||
|
- NotificationEndpointRelease: for `RELEASE` usage. e.g. `https://<your.domin>/relay-to/production`
|
||||||
|
|
||||||
Please check the [Establishing a Certificate-Based Connection to APNs
|
Please check the [Establishing a Certificate-Based Connection to APNs
|
||||||
](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) document to generate the certificate and exports the p12 file.
|
](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) document to generate the certificate and exports the p12 file.
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -3,3 +3,5 @@ source "https://rubygems.org"
|
||||||
gem 'arkana'
|
gem 'arkana'
|
||||||
gem "cocoapods"
|
gem "cocoapods"
|
||||||
gem "cocoapods-clean"
|
gem "cocoapods-clean"
|
||||||
|
gem "xcpretty"
|
||||||
|
|
||||||
|
|
24
Gemfile.lock
24
Gemfile.lock
|
@ -3,14 +3,14 @@ GEM
|
||||||
specs:
|
specs:
|
||||||
CFPropertyList (3.0.5)
|
CFPropertyList (3.0.5)
|
||||||
rexml
|
rexml
|
||||||
activesupport (6.1.5.1)
|
activesupport (6.1.7)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
zeitwerk (~> 2.3)
|
zeitwerk (~> 2.3)
|
||||||
addressable (2.8.0)
|
addressable (2.8.1)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 6.0)
|
||||||
algoliasearch (1.27.5)
|
algoliasearch (1.27.5)
|
||||||
httpclient (~> 2.8, >= 2.8.3)
|
httpclient (~> 2.8, >= 2.8.3)
|
||||||
json (>= 1.5.1)
|
json (>= 1.5.1)
|
||||||
|
@ -70,38 +70,42 @@ GEM
|
||||||
fuzzy_match (2.0.4)
|
fuzzy_match (2.0.4)
|
||||||
gh_inspector (1.1.3)
|
gh_inspector (1.1.3)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.10.0)
|
i18n (1.12.0)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
json (2.6.1)
|
json (2.6.2)
|
||||||
minitest (5.15.0)
|
minitest (5.16.3)
|
||||||
molinillo (0.8.0)
|
molinillo (0.8.0)
|
||||||
nanaimo (0.3.0)
|
nanaimo (0.3.0)
|
||||||
nap (1.1.0)
|
nap (1.1.0)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
public_suffix (4.0.7)
|
public_suffix (4.0.7)
|
||||||
rexml (3.2.5)
|
rexml (3.2.5)
|
||||||
|
rouge (2.0.7)
|
||||||
ruby-macho (2.5.1)
|
ruby-macho (2.5.1)
|
||||||
typhoeus (1.4.0)
|
typhoeus (1.4.0)
|
||||||
ethon (>= 0.9.0)
|
ethon (>= 0.9.0)
|
||||||
tzinfo (2.0.4)
|
tzinfo (2.0.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
xcodeproj (1.21.0)
|
xcodeproj (1.22.0)
|
||||||
CFPropertyList (>= 2.3.3, < 4.0)
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
atomos (~> 0.1.3)
|
atomos (~> 0.1.3)
|
||||||
claide (>= 1.0.2, < 2.0)
|
claide (>= 1.0.2, < 2.0)
|
||||||
colored2 (~> 3.1)
|
colored2 (~> 3.1)
|
||||||
nanaimo (~> 0.3.0)
|
nanaimo (~> 0.3.0)
|
||||||
rexml (~> 3.2.4)
|
rexml (~> 3.2.4)
|
||||||
|
xcpretty (0.3.0)
|
||||||
|
rouge (~> 2.0.7)
|
||||||
yaml (0.2.0)
|
yaml (0.2.0)
|
||||||
zeitwerk (2.5.4)
|
zeitwerk (2.6.3)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
arm64-darwin-21
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
arkana
|
arkana
|
||||||
cocoapods
|
cocoapods
|
||||||
cocoapods-clean
|
cocoapods-clean
|
||||||
|
xcpretty
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.3.17
|
2.3.17
|
||||||
|
|
|
@ -224,17 +224,17 @@
|
||||||
<key>NSStringFormatValueTypeKey</key>
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
<string>ld</string>
|
<string>ld</string>
|
||||||
<key>zero</key>
|
<key>zero</key>
|
||||||
<string>لا إعاد تدوين</string>
|
<string>لَا إعادَةُ تَدوين</string>
|
||||||
<key>one</key>
|
<key>one</key>
|
||||||
<string>إعادةُ تدوينٍ واحِدة</string>
|
<string>إعادَةُ تَدوينٍ واحِدَة</string>
|
||||||
<key>two</key>
|
<key>two</key>
|
||||||
<string>إعادتا تدوين</string>
|
<string>إعادَتَا تَدوين</string>
|
||||||
<key>few</key>
|
<key>few</key>
|
||||||
<string>%ld إعاداتِ تدوين</string>
|
<string>%ld إعادَاتِ تَدوين</string>
|
||||||
<key>many</key>
|
<key>many</key>
|
||||||
<string>%ld إعادةٍ للتدوين</string>
|
<string>%ld إعادَةٍ لِلتَّدوين</string>
|
||||||
<key>other</key>
|
<key>other</key>
|
||||||
<string>%ld إعادة تدوين</string>
|
<string>%ld إعادَة تَدوين</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>plural.count.reply</key>
|
<key>plural.count.reply</key>
|
||||||
|
|
|
@ -348,7 +348,7 @@
|
||||||
"Publishing": "Publication en cours ...",
|
"Publishing": "Publication en cours ...",
|
||||||
"accessibility": {
|
"accessibility": {
|
||||||
"logo_label": "Bouton logo",
|
"logo_label": "Bouton logo",
|
||||||
"logo_hint": "Tap to scroll to top and tap again to previous location"
|
"logo_hint": "Appuyez pour faire défiler vers le haut et appuyez à nouveau vers l'emplacement précédent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -546,10 +546,10 @@
|
||||||
"show_mentions": "Afficher les mentions"
|
"show_mentions": "Afficher les mentions"
|
||||||
},
|
},
|
||||||
"follow_request": {
|
"follow_request": {
|
||||||
"accept": "Accept",
|
"accept": "Accepter",
|
||||||
"accepted": "Accepted",
|
"accepted": "Accepté",
|
||||||
"reject": "reject",
|
"reject": "rejeter",
|
||||||
"rejected": "Rejected"
|
"rejected": "Rejeté"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thread": {
|
"thread": {
|
||||||
|
|
|
@ -546,10 +546,10 @@
|
||||||
"show_mentions": "Qalkirinan nîşan bike"
|
"show_mentions": "Qalkirinan nîşan bike"
|
||||||
},
|
},
|
||||||
"follow_request": {
|
"follow_request": {
|
||||||
"accept": "Accept",
|
"accept": "Bipejirîne",
|
||||||
"accepted": "Accepted",
|
"accepted": "Pejirandî",
|
||||||
"reject": "reject",
|
"reject": "nepejirîne",
|
||||||
"rejected": "Rejected"
|
"rejected": "Nepejirandî"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thread": {
|
"thread": {
|
||||||
|
|
|
@ -546,10 +546,10 @@
|
||||||
"show_mentions": "แสดงการกล่าวถึง"
|
"show_mentions": "แสดงการกล่าวถึง"
|
||||||
},
|
},
|
||||||
"follow_request": {
|
"follow_request": {
|
||||||
"accept": "Accept",
|
"accept": "ยอมรับ",
|
||||||
"accepted": "Accepted",
|
"accepted": "ยอมรับแล้ว",
|
||||||
"reject": "reject",
|
"reject": "ปฏิเสธ",
|
||||||
"rejected": "Rejected"
|
"rejected": "ปฏิเสธแล้ว"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thread": {
|
"thread": {
|
||||||
|
|
|
@ -3866,7 +3866,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||||
|
@ -3896,7 +3896,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||||
|
@ -4069,7 +4069,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||||
|
@ -4136,7 +4136,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4159,7 +4159,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4183,7 +4183,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4207,7 +4207,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4231,7 +4231,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4255,7 +4255,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4279,7 +4279,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4366,7 +4366,7 @@
|
||||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||||
|
@ -4426,13 +4426,43 @@
|
||||||
};
|
};
|
||||||
name = "Release Snapshot";
|
name = "Release Snapshot";
|
||||||
};
|
};
|
||||||
|
DBEB19E527E4658E00B0E80E /* Release Snapshot */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = 3E08A432F40BA7B9CAA9DB68 /* Pods-AppShared.release snapshot.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
|
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||||
|
DYLIB_CURRENT_VERSION = 147;
|
||||||
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
|
INFOPLIST_FILE = AppShared/Info.plist;
|
||||||
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@loader_path/Frameworks",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.AppShared;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
VERSION_INFO_PREFIX = "";
|
||||||
|
};
|
||||||
|
name = "Release Snapshot";
|
||||||
|
};
|
||||||
DBEB19E627E4658E00B0E80E /* Release Snapshot */ = {
|
DBEB19E627E4658E00B0E80E /* Release Snapshot */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4455,7 +4485,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4479,7 +4509,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
INFOPLIST_FILE = MastodonIntent/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4504,7 +4534,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
@ -4528,7 +4558,7 @@
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 144;
|
CURRENT_PROJECT_VERSION = 147;
|
||||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
|
|
@ -99,6 +99,11 @@
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>20</integer>
|
||||||
|
</dict>
|
||||||
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
|
@ -112,12 +117,12 @@
|
||||||
<key>NotificationService.xcscheme_^#shared#^_</key>
|
<key>NotificationService.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>18</integer>
|
<integer>24</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>17</integer>
|
<integer>25</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
|
|
@ -20,7 +20,7 @@ final public class SceneCoordinator {
|
||||||
|
|
||||||
private weak var scene: UIScene!
|
private weak var scene: UIScene!
|
||||||
private weak var sceneDelegate: SceneDelegate!
|
private weak var sceneDelegate: SceneDelegate!
|
||||||
private weak var appContext: AppContext!
|
private(set) weak var appContext: AppContext!
|
||||||
|
|
||||||
private(set) var authContext: AuthContext?
|
private(set) var authContext: AuthContext?
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAppTransportSecurity</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSExceptionDomains</key>
|
|
||||||
<dict>
|
|
||||||
<key>onion</key>
|
|
||||||
<dict>
|
|
||||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
|
||||||
<true/>
|
|
||||||
<key>NSIncludesSubdomains</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
@ -30,7 +17,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -43,7 +30,7 @@
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
<key>ITSAppUsesNonExemptEncryption</key>
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>LSApplicationQueriesSchemes</key>
|
<key>LSApplicationQueriesSchemes</key>
|
||||||
|
@ -59,6 +46,19 @@
|
||||||
</array>
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionDomains</key>
|
||||||
|
<dict>
|
||||||
|
<key>onion</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSIncludesSubdomains</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>NSUserActivityTypes</key>
|
<key>NSUserActivityTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<string>SendPostIntent</string>
|
<string>SendPostIntent</string>
|
||||||
|
@ -103,6 +103,10 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>remote-notification</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>Main</string>
|
<string>Main</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
|
|
@ -79,7 +79,7 @@ final class ProfileHeaderView: UIView {
|
||||||
let followsYouLabel: UILabel = {
|
let followsYouLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
|
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
|
||||||
label.text = "Follows You" // TODO: i18n
|
label.text = L10n.Scene.Profile.Header.followsYou
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
let followsYouMaskView = UIView()
|
let followsYouMaskView = UIView()
|
||||||
|
|
|
@ -106,6 +106,14 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
|
||||||
completionHandler([.sound])
|
completionHandler([.sound])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// notification present in the background (or resume from background)
|
||||||
|
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult {
|
||||||
|
let shortcutItems = try? await appContext.notificationService.unreadApplicationShortcutItems()
|
||||||
|
UIApplication.shared.shortcutItems = shortcutItems
|
||||||
|
return .noData
|
||||||
|
}
|
||||||
|
|
||||||
// response to user action for notification (e.g. redirect to post)
|
// response to user action for notification (e.g. redirect to post)
|
||||||
func userNotificationCenter(
|
func userNotificationCenter(
|
||||||
_ center: UNUserNotificationCenter,
|
_ center: UNUserNotificationCenter,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import UIKit
|
||||||
import Combine
|
import Combine
|
||||||
import CoreDataStack
|
import CoreDataStack
|
||||||
import MastodonCore
|
import MastodonCore
|
||||||
|
import MastodonExtension
|
||||||
|
|
||||||
#if PROFILE
|
#if PROFILE
|
||||||
import FPSIndicator
|
import FPSIndicator
|
||||||
|
@ -110,7 +111,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
AppContext.shared.statusFilterService.filterUpdatePublisher.send()
|
AppContext.shared.statusFilterService.filterUpdatePublisher.send()
|
||||||
|
|
||||||
if let shortcutItem = savedShortCutItem {
|
if let shortcutItem = savedShortCutItem {
|
||||||
_ = handler(shortcutItem: shortcutItem)
|
Task {
|
||||||
|
_ = await handler(shortcutItem: shortcutItem)
|
||||||
|
}
|
||||||
savedShortCutItem = nil
|
savedShortCutItem = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,14 +137,43 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SceneDelegate {
|
extension SceneDelegate {
|
||||||
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
|
||||||
completionHandler(handler(shortcutItem: shortcutItem))
|
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem) async -> Bool {
|
||||||
|
return await handler(shortcutItem: shortcutItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handler(shortcutItem: UIApplicationShortcutItem) -> Bool {
|
@MainActor
|
||||||
|
private func handler(shortcutItem: UIApplicationShortcutItem) async -> Bool {
|
||||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(shortcutItem.type)")
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(shortcutItem.type)")
|
||||||
|
|
||||||
switch shortcutItem.type {
|
switch shortcutItem.type {
|
||||||
|
case NotificationService.unreadShortcutItemIdentifier:
|
||||||
|
guard let coordinator = self.coordinator else { return false }
|
||||||
|
|
||||||
|
guard let accessToken = shortcutItem.userInfo?["accessToken"] as? String else {
|
||||||
|
assertionFailure()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
let request = MastodonAuthentication.sortedFetchRequest
|
||||||
|
request.predicate = MastodonAuthentication.predicate(userAccessToken: accessToken)
|
||||||
|
request.fetchLimit = 1
|
||||||
|
|
||||||
|
guard let authentication = try? coordinator.appContext.managedObjectContext.fetch(request).first else {
|
||||||
|
assertionFailure()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let _isActive = try? await coordinator.appContext.authenticationService.activeMastodonUser(
|
||||||
|
domain: authentication.domain,
|
||||||
|
userID: authentication.userID
|
||||||
|
)
|
||||||
|
|
||||||
|
guard _isActive == true else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
coordinator.switchToTabBar(tab: .notification)
|
||||||
|
|
||||||
case "org.joinmastodon.app.new-post":
|
case "org.joinmastodon.app.new-post":
|
||||||
if coordinator?.tabBarController.topMost is ComposeViewController {
|
if coordinator?.tabBarController.topMost is ComposeViewController {
|
||||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): composing…")
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): composing…")
|
||||||
|
@ -158,6 +190,7 @@ extension SceneDelegate {
|
||||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): not authenticated")
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): not authenticated")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case "org.joinmastodon.app.search":
|
case "org.joinmastodon.app.search":
|
||||||
coordinator?.switchToTabBar(tab: .search)
|
coordinator?.switchToTabBar(tab: .search)
|
||||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): select search tab")
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): select search tab")
|
||||||
|
@ -166,6 +199,7 @@ extension SceneDelegate {
|
||||||
searchViewController.searchBarTapPublisher.send()
|
searchViewController.searchBarTapPublisher.send()
|
||||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): trigger search")
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): trigger search")
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assertionFailure()
|
assertionFailure()
|
||||||
break
|
break
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionAttributes</key>
|
<key>NSExtensionAttributes</key>
|
||||||
|
|
|
@ -73,7 +73,7 @@ let package = Package(
|
||||||
.target(
|
.target(
|
||||||
name: "MastodonCommon",
|
name: "MastodonCommon",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"MastodonExtension"
|
"MastodonExtension",
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.target(
|
.target(
|
||||||
|
|
|
@ -130,17 +130,17 @@ public enum Asset {
|
||||||
}
|
}
|
||||||
public enum Scene {
|
public enum Scene {
|
||||||
public enum Compose {
|
public enum Compose {
|
||||||
|
public static let earth = ImageAsset(name: "Scene/Compose/Earth")
|
||||||
|
public static let mention = ImageAsset(name: "Scene/Compose/Mention")
|
||||||
|
public static let more = ImageAsset(name: "Scene/Compose/More")
|
||||||
|
public static let people = ImageAsset(name: "Scene/Compose/People")
|
||||||
public static let buttonTint = ColorAsset(name: "Scene/Compose/button.tint")
|
public static let buttonTint = ColorAsset(name: "Scene/Compose/button.tint")
|
||||||
public static let chatWarningFill = ImageAsset(name: "Scene/Compose/chat.warning.fill")
|
public static let chatWarningFill = ImageAsset(name: "Scene/Compose/chat.warning.fill")
|
||||||
public static let chatWarning = ImageAsset(name: "Scene/Compose/chat.warning")
|
public static let chatWarning = ImageAsset(name: "Scene/Compose/chat.warning")
|
||||||
public static let earth = ImageAsset(name: "Scene/Compose/earth")
|
|
||||||
public static let emojiFill = ImageAsset(name: "Scene/Compose/emoji.fill")
|
public static let emojiFill = ImageAsset(name: "Scene/Compose/emoji.fill")
|
||||||
public static let emoji = ImageAsset(name: "Scene/Compose/emoji")
|
public static let emoji = ImageAsset(name: "Scene/Compose/emoji")
|
||||||
public static let media = ImageAsset(name: "Scene/Compose/media")
|
public static let media = ImageAsset(name: "Scene/Compose/media")
|
||||||
public static let mention = ImageAsset(name: "Scene/Compose/mention")
|
|
||||||
public static let more = ImageAsset(name: "Scene/Compose/more")
|
|
||||||
public static let peopleAdd = ImageAsset(name: "Scene/Compose/people.add")
|
public static let peopleAdd = ImageAsset(name: "Scene/Compose/people.add")
|
||||||
public static let people = ImageAsset(name: "Scene/Compose/people")
|
|
||||||
public static let pollFill = ImageAsset(name: "Scene/Compose/poll.fill")
|
public static let pollFill = ImageAsset(name: "Scene/Compose/poll.fill")
|
||||||
public static let poll = ImageAsset(name: "Scene/Compose/poll")
|
public static let poll = ImageAsset(name: "Scene/Compose/poll")
|
||||||
public static let reorderDot = ImageAsset(name: "Scene/Compose/reorder.dot")
|
public static let reorderDot = ImageAsset(name: "Scene/Compose/reorder.dot")
|
||||||
|
|
|
@ -37,9 +37,11 @@ public final class AppSecret {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
self.notificationEndpoint = Keys.Debug().notificationEndpoint
|
let keys = Keys.Debug()
|
||||||
|
self.notificationEndpoint = keys.notificationEndpoint
|
||||||
#else
|
#else
|
||||||
self.notificationEndpoint = Keys.Release().notificationEndpoint
|
let keys = Keys.Release()
|
||||||
|
self.notificationEndpoint = keys.notificationEndpoint
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,12 @@ import CoreData
|
||||||
import CoreDataStack
|
import CoreDataStack
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
import MastodonCommon
|
import MastodonCommon
|
||||||
|
import MastodonLocalization
|
||||||
|
|
||||||
public final class NotificationService {
|
public final class NotificationService {
|
||||||
|
|
||||||
|
public static let unreadShortcutItemIdentifier = "org.joinmastodon.app.NotificationService.unread-shortcut"
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
let workingQueue = DispatchQueue(label: "org.joinmastodon.app.NotificationService.working-queue")
|
let workingQueue = DispatchQueue(label: "org.joinmastodon.app.NotificationService.working-queue")
|
||||||
|
@ -75,6 +78,9 @@ public final class NotificationService {
|
||||||
|
|
||||||
UserDefaults.shared.notificationBadgeCount = count
|
UserDefaults.shared.notificationBadgeCount = count
|
||||||
UIApplication.shared.applicationIconBadgeNumber = count
|
UIApplication.shared.applicationIconBadgeNumber = count
|
||||||
|
Task { @MainActor in
|
||||||
|
UIApplication.shared.shortcutItems = try? await self.unreadApplicationShortcutItems()
|
||||||
|
}
|
||||||
|
|
||||||
self.unreadNotificationCountDidUpdate.send()
|
self.unreadNotificationCountDidUpdate.send()
|
||||||
}
|
}
|
||||||
|
@ -101,6 +107,37 @@ extension NotificationService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension NotificationService {
|
||||||
|
public func unreadApplicationShortcutItems() async throws -> [UIApplicationShortcutItem] {
|
||||||
|
guard let authenticationService = self.authenticationService else { return [] }
|
||||||
|
let managedObjectContext = authenticationService.managedObjectContext
|
||||||
|
return try await managedObjectContext.perform {
|
||||||
|
var items: [UIApplicationShortcutItem] = []
|
||||||
|
for object in authenticationService.mastodonAuthentications {
|
||||||
|
guard let authentication = managedObjectContext.object(with: object.objectID) as? MastodonAuthentication else { continue }
|
||||||
|
let accessToken = authentication.userAccessToken
|
||||||
|
let count = UserDefaults.shared.getNotificationCountWithAccessToken(accessToken: accessToken)
|
||||||
|
guard count > 0 else { continue }
|
||||||
|
|
||||||
|
let title = "@\(authentication.user.acctWithDomain)"
|
||||||
|
let subtitle = L10n.A11y.Plural.Count.Unread.notification(count)
|
||||||
|
|
||||||
|
let item = UIApplicationShortcutItem(
|
||||||
|
type: NotificationService.unreadShortcutItemIdentifier,
|
||||||
|
localizedTitle: title,
|
||||||
|
localizedSubtitle: subtitle,
|
||||||
|
icon: nil,
|
||||||
|
userInfo: [
|
||||||
|
"accessToken": accessToken as NSSecureCoding
|
||||||
|
]
|
||||||
|
)
|
||||||
|
items.append(item)
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension NotificationService {
|
extension NotificationService {
|
||||||
|
|
||||||
func dequeueNotificationViewModel(
|
func dequeueNotificationViewModel(
|
||||||
|
|
|
@ -224,17 +224,17 @@
|
||||||
<key>NSStringFormatValueTypeKey</key>
|
<key>NSStringFormatValueTypeKey</key>
|
||||||
<string>ld</string>
|
<string>ld</string>
|
||||||
<key>zero</key>
|
<key>zero</key>
|
||||||
<string>لا إعاد تدوين</string>
|
<string>لَا إعادَةُ تَدوين</string>
|
||||||
<key>one</key>
|
<key>one</key>
|
||||||
<string>إعادةُ تدوينٍ واحِدة</string>
|
<string>إعادَةُ تَدوينٍ واحِدَة</string>
|
||||||
<key>two</key>
|
<key>two</key>
|
||||||
<string>إعادتا تدوين</string>
|
<string>إعادَتَا تَدوين</string>
|
||||||
<key>few</key>
|
<key>few</key>
|
||||||
<string>%ld إعاداتِ تدوين</string>
|
<string>%ld إعادَاتِ تَدوين</string>
|
||||||
<key>many</key>
|
<key>many</key>
|
||||||
<string>%ld إعادةٍ للتدوين</string>
|
<string>%ld إعادَةٍ لِلتَّدوين</string>
|
||||||
<key>other</key>
|
<key>other</key>
|
||||||
<string>%ld إعادة تدوين</string>
|
<string>%ld إعادَة تَدوين</string>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>plural.count.reply</key>
|
<key>plural.count.reply</key>
|
||||||
|
|
|
@ -216,17 +216,17 @@ téléversé sur Mastodon.";
|
||||||
"Scene.Follower.Title" = "abonné·e";
|
"Scene.Follower.Title" = "abonné·e";
|
||||||
"Scene.Following.Footer" = "Les abonnés issus des autres serveurs ne sont pas affichés.";
|
"Scene.Following.Footer" = "Les abonnés issus des autres serveurs ne sont pas affichés.";
|
||||||
"Scene.Following.Title" = "following";
|
"Scene.Following.Title" = "following";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location";
|
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Appuyez pour faire défiler vers le haut et appuyez à nouveau vers l'emplacement précédent";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Bouton logo";
|
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Bouton logo";
|
||||||
"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Voir les nouvelles publications";
|
"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Voir les nouvelles publications";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Offline" = "Hors ligne";
|
"Scene.HomeTimeline.NavigationBarState.Offline" = "Hors ligne";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Published" = "Publié!";
|
"Scene.HomeTimeline.NavigationBarState.Published" = "Publié!";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publication en cours ...";
|
"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publication en cours ...";
|
||||||
"Scene.HomeTimeline.Title" = "Accueil";
|
"Scene.HomeTimeline.Title" = "Accueil";
|
||||||
"Scene.Notification.FollowRequest.Accept" = "Accept";
|
"Scene.Notification.FollowRequest.Accept" = "Accepter";
|
||||||
"Scene.Notification.FollowRequest.Accepted" = "Accepted";
|
"Scene.Notification.FollowRequest.Accepted" = "Accepté";
|
||||||
"Scene.Notification.FollowRequest.Reject" = "reject";
|
"Scene.Notification.FollowRequest.Reject" = "rejeter";
|
||||||
"Scene.Notification.FollowRequest.Rejected" = "Rejected";
|
"Scene.Notification.FollowRequest.Rejected" = "Rejeté";
|
||||||
"Scene.Notification.Keyobard.ShowEverything" = "Tout Afficher";
|
"Scene.Notification.Keyobard.ShowEverything" = "Tout Afficher";
|
||||||
"Scene.Notification.Keyobard.ShowMentions" = "Afficher les mentions";
|
"Scene.Notification.Keyobard.ShowMentions" = "Afficher les mentions";
|
||||||
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "a ajouté votre message à ses favoris";
|
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "a ajouté votre message à ses favoris";
|
||||||
|
|
|
@ -224,10 +224,10 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin.";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Published" = "Hate weşandin!";
|
"Scene.HomeTimeline.NavigationBarState.Published" = "Hate weşandin!";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Publishing" = "Şandî tê weşandin...";
|
"Scene.HomeTimeline.NavigationBarState.Publishing" = "Şandî tê weşandin...";
|
||||||
"Scene.HomeTimeline.Title" = "Serrûpel";
|
"Scene.HomeTimeline.Title" = "Serrûpel";
|
||||||
"Scene.Notification.FollowRequest.Accept" = "Accept";
|
"Scene.Notification.FollowRequest.Accept" = "Bipejirîne";
|
||||||
"Scene.Notification.FollowRequest.Accepted" = "Accepted";
|
"Scene.Notification.FollowRequest.Accepted" = "Pejirandî";
|
||||||
"Scene.Notification.FollowRequest.Reject" = "reject";
|
"Scene.Notification.FollowRequest.Reject" = "nepejirîne";
|
||||||
"Scene.Notification.FollowRequest.Rejected" = "Rejected";
|
"Scene.Notification.FollowRequest.Rejected" = "Nepejirandî";
|
||||||
"Scene.Notification.Keyobard.ShowEverything" = "Her tiştî nîşan bide";
|
"Scene.Notification.Keyobard.ShowEverything" = "Her tiştî nîşan bide";
|
||||||
"Scene.Notification.Keyobard.ShowMentions" = "Qalkirinan nîşan bike";
|
"Scene.Notification.Keyobard.ShowMentions" = "Qalkirinan nîşan bike";
|
||||||
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "şandiya te hez kir";
|
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "şandiya te hez kir";
|
||||||
|
|
|
@ -223,10 +223,10 @@
|
||||||
"Scene.HomeTimeline.NavigationBarState.Published" = "เผยแพร่แล้ว!";
|
"Scene.HomeTimeline.NavigationBarState.Published" = "เผยแพร่แล้ว!";
|
||||||
"Scene.HomeTimeline.NavigationBarState.Publishing" = "กำลังเผยแพร่โพสต์...";
|
"Scene.HomeTimeline.NavigationBarState.Publishing" = "กำลังเผยแพร่โพสต์...";
|
||||||
"Scene.HomeTimeline.Title" = "หน้าแรก";
|
"Scene.HomeTimeline.Title" = "หน้าแรก";
|
||||||
"Scene.Notification.FollowRequest.Accept" = "Accept";
|
"Scene.Notification.FollowRequest.Accept" = "ยอมรับ";
|
||||||
"Scene.Notification.FollowRequest.Accepted" = "Accepted";
|
"Scene.Notification.FollowRequest.Accepted" = "ยอมรับแล้ว";
|
||||||
"Scene.Notification.FollowRequest.Reject" = "reject";
|
"Scene.Notification.FollowRequest.Reject" = "ปฏิเสธ";
|
||||||
"Scene.Notification.FollowRequest.Rejected" = "Rejected";
|
"Scene.Notification.FollowRequest.Rejected" = "ปฏิเสธแล้ว";
|
||||||
"Scene.Notification.Keyobard.ShowEverything" = "แสดงทุกอย่าง";
|
"Scene.Notification.Keyobard.ShowEverything" = "แสดงทุกอย่าง";
|
||||||
"Scene.Notification.Keyobard.ShowMentions" = "แสดงการกล่าวถึง";
|
"Scene.Notification.Keyobard.ShowMentions" = "แสดงการกล่าวถึง";
|
||||||
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "ได้ชื่นชอบโพสต์ของคุณ";
|
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "ได้ชื่นชอบโพสต์ของคุณ";
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.4.5</string>
|
<string>1.4.6</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>144</string>
|
<string>147</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionAttributes</key>
|
<key>NSExtensionAttributes</key>
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/zsh
|
||||||
|
|
||||||
|
# Xcode Cloud scripts
|
||||||
|
|
||||||
|
set -xeu
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
|
# list hardware
|
||||||
|
system_profiler SPSoftwareDataType SPHardwareDataType
|
||||||
|
|
||||||
|
echo $PWD
|
||||||
|
cd $CI_WORKSPACE
|
||||||
|
echo $PWD
|
||||||
|
|
||||||
|
# install ruby from homebrew
|
||||||
|
brew install ruby
|
||||||
|
echo 'export PATH="/Users/local/Homebrew/opt/ruby/bin:$PATH"' >> ~/.zshrc
|
||||||
|
source ~/.zshrc
|
||||||
|
|
||||||
|
ruby --version
|
||||||
|
which gem
|
||||||
|
|
||||||
|
# workaround default installation location cannot access without sudo problem
|
||||||
|
echo 'export GEM_HOME=$HOME/gems' >>~/.bash_profile
|
||||||
|
echo 'export PATH=$HOME/gems/bin:$PATH' >>~/.bash_profile
|
||||||
|
export GEM_HOME=$HOME/gems
|
||||||
|
export PATH="$GEM_HOME/bin:$PATH"
|
||||||
|
|
||||||
|
# install bundle gem
|
||||||
|
gem install bundler --install-dir $GEM_HOME
|
||||||
|
|
||||||
|
# setup gems
|
||||||
|
bundle install
|
||||||
|
|
||||||
|
bundle exec arkana
|
||||||
|
bundle exec pod install
|
Loading…
Reference in New Issue