Compare commits
380 commits
Author | SHA1 | Date | |
---|---|---|---|
f40aeb9cac | |||
1578896b3e | |||
ba3d8b1882 | |||
04af087c4b | |||
a9398c25af | |||
13d721912b | |||
e3d4e693d2 | |||
86c053344b | |||
a996aace80 | |||
18a1d17230 | |||
69cb9a20f9 | |||
bab2b4be9c | |||
bb005386df | |||
c77bb992b4 | |||
7caf00d07d | |||
6ed760a775 | |||
ecd149b3d2 | |||
9aaf0b2350 | |||
2d6cce6b01 | |||
48faddebea | |||
a8039df22d | |||
e21ec0bd1f | |||
9c42a3d7cc | |||
54a16b2c9a | |||
a6f3068728 | |||
f04258ec04 | |||
8468e51c17 | |||
e9a2d3e151 | |||
1f56fa1b9b | |||
ccad00a094 | |||
51fecb01f5 | |||
c29de44d8c | |||
1d79832544 | |||
a37316c56f | |||
189e10f2b4 | |||
24d5ecd119 | |||
ee6f003073 | |||
7328c00006 | |||
a6fd8d1137 | |||
ea31cda3c2 | |||
8ab7b5ac69 | |||
7aebe530dd | |||
a2afd4f58f | |||
88218cd6ec | |||
c4dee39efe | |||
73651cb7f1 | |||
dd1615f0e3 | |||
6bd14e0f8d | |||
1ca4a74ff0 | |||
c3edabb183 | |||
ba4cc899f8 | |||
5a93184c6d | |||
66754ecc7c | |||
e857439a02 | |||
ed620e86ca | |||
936bc96ff7 | |||
37b441a43d | |||
07af494dcb | |||
49a5c6a56a | |||
4e4d903c44 | |||
abcd4cc321 | |||
6a7df1065d | |||
c0b855ea55 | |||
4c3047b0b9 | |||
899b92e390 | |||
e71c55b488 | |||
361b5f1d84 | |||
ad61600328 | |||
5f1f71068c | |||
3782300b27 | |||
7d47834903 | |||
65a83fa636 | |||
8038e8e6af | |||
eb82a67671 | |||
bc5bb8272a | |||
d2ead5b6d1 | |||
d22370959c | |||
2c9b841f30 | |||
2e3cf4aace | |||
7de563a6eb | |||
3aae2e6623 | |||
5c32c24ae5 | |||
bb56047ee2 | |||
924ada6606 | |||
e6f96d1899 | |||
058500f91e | |||
fd3d9fc2bc | |||
9a7e6b7cb0 | |||
bc2a09891a | |||
7c343eb4e9 | |||
15d7d1dabd | |||
f4ec69a37f | |||
732a253c7a | |||
9c67af8451 | |||
b56da94a7c | |||
e612fbdf7c | |||
f46a0cee17 | |||
4a90d979e3 | |||
9e4323f317 | |||
24ce872849 | |||
1f858414d8 | |||
2d988d48c1 | |||
21d9fd7b59 | |||
cca6472a32 | |||
c769e80bb6 | |||
2986d2b177 | |||
29312d1be2 | |||
9ddf0e65fc | |||
bc74a50a6a | |||
d55d6a0371 | |||
773fdc318b | |||
7423aba92a | |||
77aa50ef19 | |||
dfc213a19a | |||
20900f573f | |||
046a41e8ef | |||
fcd56ab7a0 | |||
923927cddd | |||
219703ecc7 | |||
0739264005 | |||
6f8bec4737 | |||
d8e6e6cfb1 | |||
e7bc857231 | |||
35d249f7c9 | |||
7b7e65bf31 | |||
9542002534 | |||
3020d831e4 | |||
a0e022b8de | |||
b9b3d0e727 | |||
4bf476daea | |||
d1fd97794a | |||
f14ca6e529 | |||
75bb4f43dd | |||
cfd6eed159 | |||
d10adf1fd9 | |||
3b07d56b1d | |||
b4dbda8722 | |||
827765f251 | |||
e7702e1ad0 | |||
70f58aa08d | |||
cf81054366 | |||
f67163e4b0 | |||
9bd967cddf | |||
551e6b1412 | |||
1c76d50bde | |||
2a6afb4092 | |||
b348f37f1a | |||
de757c58f8 | |||
7268b5a38e | |||
b8cf446406 | |||
6e497fae5b | |||
586e4f525e | |||
7f689bbb9c | |||
9dfd9c27c7 | |||
9cf16b2f30 | |||
1299202bba | |||
f16f0d514b | |||
096996c242 | |||
c7bd5a1d94 | |||
20f4eb9c71 | |||
74590542bc | |||
49b1b0e96c | |||
3eec5c0eec | |||
016e4d5d57 | |||
ba071eb4c8 | |||
d2014d3aec | |||
621f0d0864 | |||
eeff60bf98 | |||
245d35db82 | |||
62eeba5334 | |||
46b8fbde29 | |||
9a8568d3fa | |||
a6ccdc029b | |||
ed9a4a598d | |||
13af2d7e3f | |||
2b446833da | |||
0b96b76641 | |||
78eee1e855 | |||
b7937e3580 | |||
9320b2f114 | |||
ad7bc999d3 | |||
b41fd2d6ce | |||
a79a181d6f | |||
fb944f9c48 | |||
3c82af0273 | |||
3577254f08 | |||
abff6218a4 | |||
1be9a7b941 | |||
18381e22e2 | |||
e2273c436a | |||
2296dd4658 | |||
92662665b9 | |||
17387626b8 | |||
e00fd49d89 | |||
97798b2c35 | |||
90a2a19bb1 | |||
21d54cc546 | |||
76638911ee | |||
0b7fed2e9a | |||
328ee2d090 | |||
ebdd5b9feb | |||
f79117eff1 | |||
709dd79e25 | |||
bf7cdc3712 | |||
f12d0600f7 | |||
b6f11e4e08 | |||
76a8f45478 | |||
e03747aa45 | |||
8568d6cc59 | |||
1a0b52d268 | |||
0dea624060 | |||
a4927fd30c | |||
b8be6b79af | |||
ddaf4f9fde | |||
d9f115ba67 | |||
a8f8933e11 | |||
35f6dc8d14 | |||
70eea46aef | |||
788fab930b | |||
7c8ea23ae9 | |||
54dd7521c0 | |||
5eccb5c294 | |||
254962c5c0 | |||
a737c61d15 | |||
27da37e9ec | |||
6d12f2528d | |||
231b622f4e | |||
73a02db57f | |||
ab69a0683b | |||
34d8d8bb46 | |||
79d062f168 | |||
49e47f3dfd | |||
c55259efbb | |||
99c8ea6f99 | |||
a11b6ac2a5 | |||
8c68aa711d | |||
68b7d469f5 | |||
fab23cbafc | |||
2f5307bfc7 | |||
801b6c5682 | |||
802eae750d | |||
afa31411e1 | |||
af2a69fdb1 | |||
0da8228e61 | |||
6246d7b0a5 | |||
b6c3b07ad6 | |||
71495181c6 | |||
d3558b761a | |||
f758b672f1 | |||
1c1a612d56 | |||
8ea3fa73e5 | |||
5c1f113c54 | |||
b7e8f63e86 | |||
e7864f7089 | |||
3a173a8cae | |||
b2be3778c1 | |||
bda192fdc4 | |||
adca09dfcb | |||
3e67113c19 | |||
a4cdc6fc18 | |||
c847de8f47 | |||
7ac9a750cb | |||
c86d627cee | |||
916c0d9831 | |||
14b25830ff | |||
556eb15fb4 | |||
8e8713886a | |||
e79ead5efe | |||
5d24c4d2e8 | |||
e725b6be4d | |||
6af0c36740 | |||
4ebe486816 | |||
753a0574b1 | |||
9e1b1780c9 | |||
738180665e | |||
334b09ebe3 | |||
6f42ed8de0 | |||
c09f9727f1 | |||
cd63c9ddff | |||
c4c86e1434 | |||
2c7ca2ca81 | |||
7a7066baa4 | |||
71d12aec15 | |||
d378341914 | |||
5ca5dfbd24 | |||
5ce4d0b41d | |||
75987d74aa | |||
6aae6f7e40 | |||
e6c2146217 | |||
6e981a99fc | |||
27ce7fe916 | |||
d952601528 | |||
34a482f01f | |||
8e8737b040 | |||
a80d36227e | |||
ca9dd5b469 | |||
7eb382c052 | |||
d65510493a | |||
9ade571f53 | |||
c24403094c | |||
36cc3d5207 | |||
9329bdf19b | |||
0058ce36b7 | |||
8a3c540967 | |||
e5bb521502 | |||
6435b40a51 | |||
1297331407 | |||
8c8c551686 | |||
bb55154b75 | |||
e4f7a6954b | |||
73882b0806 | |||
e473981841 | |||
0916a80a2e | |||
a0ff3596cb | |||
f401d4094d | |||
ef204cf6fd | |||
91f0df0f26 | |||
a3f29aa15b | |||
b3af5f1c45 | |||
0501ce9828 | |||
bfc1f61e4b | |||
8152db745d | |||
1f6e8e8d18 | |||
d07427b919 | |||
f674c2fa46 | |||
fcf00796b8 | |||
d94e816d63 | |||
f428118fa0 | |||
3e968525ac | |||
e6a4bd383c | |||
72b4a92bfe | |||
e61a2a32e4 | |||
6bb6a02912 | |||
c0a78ef007 | |||
80a22e55fa | |||
c3adb37da0 | |||
d399c18a82 | |||
3d29c9e600 | |||
9ec9c94c9a | |||
60ade66251 | |||
469b99f3c9 | |||
fd190378c6 | |||
6e9bff575d | |||
3a3cae21b0 | |||
3229bf0cb5 | |||
c43d1d0dda | |||
e733dc3f2a | |||
0e9a006483 | |||
8459224ab1 | |||
d46d47f97d | |||
6babd50d6e | |||
72f3af7255 | |||
2eb15b48d4 | |||
ad4995ad70 | |||
75a61cb534 | |||
1bdd31e848 | |||
2e23b08b88 | |||
6854df4b89 | |||
73323f8460 | |||
f39005c118 | |||
326d6e5d50 | |||
6cc14f8249 | |||
1eb33466ca | |||
f699c33dfb | |||
f6b7b9807f | |||
245f13d59f | |||
442a7938ca | |||
c4de2d6784 | |||
632b3f5734 | |||
924e1b6057 | |||
983c22886a | |||
f19ab2b130 | |||
13e87b41e9 | |||
c4b85679a2 | |||
0c13cbd61f | |||
aee6459bcf | |||
f235ebb720 | |||
47436daaf2 | |||
1e7c25993a | |||
6f1896caf3 |
11
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "swift" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
35
.github/workflows/validate_translations.yml
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
name: Validate Translations
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [synchronize, opened, reopened, labeled, unlabeled, edited]
|
||||
|
||||
jobs:
|
||||
main:
|
||||
name: Validate Translations
|
||||
runs-on: macOS-latest
|
||||
steps:
|
||||
- name: git checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: ruby versions
|
||||
run: |
|
||||
ruby --version
|
||||
gem --version
|
||||
bundler --version
|
||||
|
||||
- name: ruby setup
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: 3.3
|
||||
bundler-cache: true
|
||||
|
||||
# additional steps here, if needed
|
||||
|
||||
- name: Clone SwiftPolyglot
|
||||
run: git clone https://github.com/appdecostudio/SwiftPolyglot.git --branch 0.2.0
|
||||
|
||||
- name: Build and Run SwiftPolyglot
|
||||
run: |
|
||||
swift build --package-path ./SwiftPolyglot --configuration release
|
||||
swift run --package-path ./SwiftPolyglot swiftpolyglot "en,eu,be,ca,zh-Hans,zh-Hant,nl,en-GB,fr,de,it,ja,ko,nb,pl,pt-BR,es,tr,uk"
|
|
@ -26,8 +26,6 @@
|
|||
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F24EEB729360C330042359D /* Preview Assets.xcassets */; };
|
||||
9F295540292B6C3400E0E81B /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F29553F292B6C3400E0E81B /* Timeline */; };
|
||||
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A540629699698009B2D7C /* SupportAppView.swift */; };
|
||||
9F2A540A29699705009B2D7C /* ReceiptParser in Frameworks */ = {isa = PBXBuildFile; productRef = 9F2A540929699705009B2D7C /* ReceiptParser */; };
|
||||
9F2A540C29699705009B2D7C /* RevenueCat in Frameworks */ = {isa = PBXBuildFile; productRef = 9F2A540B29699705009B2D7C /* RevenueCat */; };
|
||||
9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F2A540D2969A0B0009B2D7C /* StoreKit.framework */; };
|
||||
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5410296A1429009B2D7C /* PushNotificationsView.swift */; };
|
||||
9F2A5419296AB631009B2D7C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5418296AB631009B2D7C /* NotificationService.swift */; };
|
||||
|
@ -41,10 +39,14 @@
|
|||
9F2B92F6295AE04800DE16D0 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F5295AE04800DE16D0 /* Tabs.swift */; };
|
||||
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */; };
|
||||
9F2B92FC295DA94500DE16D0 /* InstanceInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */; };
|
||||
9F35DB44294F9A7D00B3281A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB43294F9A7D00B3281A /* Status */; };
|
||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
||||
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4B2952005C00B3281A /* MessagesTab.swift */; };
|
||||
9F37BDDB2BE36E22007F28AD /* PostIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F37BDDA2BE36E22007F28AD /* PostIntent.swift */; };
|
||||
9F37BDDD2BE37193007F28AD /* AppIntentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F37BDDC2BE37193007F28AD /* AppIntentService.swift */; };
|
||||
9F37BDDF2BE37C35007F28AD /* TabIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F37BDDE2BE37C35007F28AD /* TabIntent.swift */; };
|
||||
9F37BDE12BE38646007F28AD /* PostImageIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F37BDE02BE38646007F28AD /* PostImageIntent.swift */; };
|
||||
9F37BDE32BE393A7007F28AD /* AppShortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F37BDE22BE393A7007F28AD /* AppShortcuts.swift */; };
|
||||
9F38A7332ACEA26100DBCD66 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */; };
|
||||
9F38A7342ACEA26100DBCD66 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */; };
|
||||
9F38A7352ACEA26100DBCD66 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */; };
|
||||
|
@ -55,6 +57,9 @@
|
|||
9F4A48192976B21900A1A038 /* ProfileTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4A48182976B21900A1A038 /* ProfileTab.swift */; };
|
||||
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F55C68C2955968700F94077 /* ExploreTab.swift */; };
|
||||
9F55C6902955993C00F94077 /* Explore in Frameworks */ = {isa = PBXBuildFile; productRef = 9F55C68F2955993C00F94077 /* Explore */; };
|
||||
9F5BE6272BF492CF0074387E /* ListEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5BE6252BF48FE10074387E /* ListEntity.swift */; };
|
||||
9F5BE6282BF492D10074387E /* ListsWidgetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5BE6232BF48FC40074387E /* ListsWidgetConfiguration.swift */; };
|
||||
9F5BE6292BF492D40074387E /* ListsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F5BE6212BF48FBA0074387E /* ListsWidget.swift */; };
|
||||
9F5E581929545BE700A53960 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9F5E581829545BE700A53960 /* Env */; };
|
||||
9F6028562B3F36AE00476078 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028552B3F36AE00476078 /* AppView.swift */; };
|
||||
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028572B3F3B7600476078 /* ToolbarTab.swift */; };
|
||||
|
@ -64,14 +69,33 @@
|
|||
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EE29674F7100AFF0BA /* QuickLook.framework */; };
|
||||
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F12967608F00AFF0BA /* AddRemoteTimelineView.swift */; };
|
||||
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F82968576500AFF0BA /* DisplaySettingsView.swift */; };
|
||||
9F7788C02BE63935004E6BEF /* InlinePostIntent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788BF2BE63935004E6BEF /* InlinePostIntent.swift */; };
|
||||
9F7788C72BE652B1004E6BEF /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7788C62BE652B1004E6BEF /* WidgetKit.framework */; };
|
||||
9F7788C92BE652B1004E6BEF /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7788C82BE652B1004E6BEF /* SwiftUI.framework */; };
|
||||
9F7788CC2BE652B1004E6BEF /* IceCubesAppWidgetsExtensionBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788CB2BE652B1004E6BEF /* IceCubesAppWidgetsExtensionBundle.swift */; };
|
||||
9F7788CE2BE652B1004E6BEF /* LatestPostsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788CD2BE652B1004E6BEF /* LatestPostsWidget.swift */; };
|
||||
9F7788D02BE652B1004E6BEF /* LatestPostsWidgetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788CF2BE652B1004E6BEF /* LatestPostsWidgetConfiguration.swift */; };
|
||||
9F7788D22BE652B2004E6BEF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F7788D12BE652B2004E6BEF /* Assets.xcassets */; };
|
||||
9F7788D62BE652B2004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9F7788C52BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex */; platformFilters = (ios, maccatalyst, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
9F7788DE2BE6543D004E6BEF /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788DD2BE6543D004E6BEF /* Account */; };
|
||||
9F7788E02BE6543D004E6BEF /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788DF2BE6543D004E6BEF /* AppAccount */; };
|
||||
9F7788E22BE6543D004E6BEF /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788E12BE6543D004E6BEF /* Env */; };
|
||||
9F7788E42BE6543D004E6BEF /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788E32BE6543D004E6BEF /* Models */; };
|
||||
9F7788E62BE6543D004E6BEF /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788E52BE6543D004E6BEF /* Network */; };
|
||||
9F7788E82BE65533004E6BEF /* AppAccountEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788E72BE65533004E6BEF /* AppAccountEntity.swift */; };
|
||||
9F7788EA2BE65585004E6BEF /* AppAccountEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788E72BE65533004E6BEF /* AppAccountEntity.swift */; };
|
||||
9F7788ED2BE78D75004E6BEF /* TimelineFilterEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788EC2BE78D75004E6BEF /* TimelineFilterEntity.swift */; };
|
||||
9F7788EE2BE78D7B004E6BEF /* TimelineFilterEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7788EC2BE78D75004E6BEF /* TimelineFilterEntity.swift */; };
|
||||
9F7788F02BE78E77004E6BEF /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7788EF2BE78E77004E6BEF /* Timeline */; };
|
||||
9F7D93942980063100EE6B7A /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7D93932980063100EE6B7A /* AppAccount */; };
|
||||
9F7D939A29805DBD00EE6B7A /* AccountSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7D939929805DBD00EE6B7A /* AccountSettingView.swift */; };
|
||||
9F8B92122BF77DBE003D37A2 /* AccountWidgetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8B920E2BF77DB4003D37A2 /* AccountWidgetConfiguration.swift */; };
|
||||
9F8B92132BF77DBE003D37A2 /* AccountWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8B92102BF77DBB003D37A2 /* AccountWidget.swift */; };
|
||||
9F8B92162BF77F0B003D37A2 /* AccountWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8B92142BF77F05003D37A2 /* AccountWidgetView.swift */; };
|
||||
9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA6FD6129C04A8800E2312C /* TranslationSettingsView.swift */; };
|
||||
9FAD85832971BF7200496AB1 /* Secret.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9FAD85822971BF7200496AB1 /* Secret.plist */; };
|
||||
9FAD858B29743F7400496AB1 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD858A29743F7400496AB1 /* ShareViewController.swift */; };
|
||||
9FAD858E29743F7400496AB1 /* (null) in Resources */ = {isa = PBXBuildFile; };
|
||||
9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */; platformFilters = (ios, maccatalyst, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
9FAD85982974405D00496AB1 /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD85972974405D00496AB1 /* Status */; };
|
||||
9FAD859A297440CB00496AB1 /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD8599297440CB00496AB1 /* KeychainSwift */; };
|
||||
9FAD859C2974422700496AB1 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859B2974422700496AB1 /* AppAccount */; };
|
||||
9FAD859E2974569B00496AB1 /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9FAD859D2974569B00496AB1 /* Account */; };
|
||||
|
@ -85,14 +109,29 @@
|
|||
9FB143D22983104A00A27BB1 /* glass.wav in Resources */ = {isa = PBXBuildFile; fileRef = 9F2A542D296B1CC0009B2D7C /* glass.wav */; };
|
||||
9FB183222AE9268800BBB692 /* IceCubesApp+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */; };
|
||||
9FB183292AE9449100BBB692 /* IceCubesApp+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */; };
|
||||
9FBA1D352B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */; };
|
||||
9FBFE63D292A715500C250E9 /* IceCubesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBFE63C292A715500C250E9 /* IceCubesApp.swift */; };
|
||||
9FBFE64E292A72BD00C250E9 /* Network in Frameworks */ = {isa = PBXBuildFile; productRef = 9FBFE64D292A72BD00C250E9 /* Network */; };
|
||||
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */; };
|
||||
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC14EF32B494D940006CEE1 /* RemoteTimelinesSettingView.swift */; };
|
||||
9FC14EF62B494DFF0006CEE1 /* RecenTagsSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FC14EF52B494DFF0006CEE1 /* RecenTagsSettingView.swift */; };
|
||||
9FC2A38B2B49D19A00DFD1C1 /* StatusKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9FC2A38A2B49D19A00DFD1C1 /* StatusKit */; };
|
||||
9FC2A38D2B49D1A200DFD1C1 /* StatusKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9FC2A38C2B49D1A200DFD1C1 /* StatusKit */; };
|
||||
9FC2A38F2B49D1AA00DFD1C1 /* StatusKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9FC2A38E2B49D1AA00DFD1C1 /* StatusKit */; };
|
||||
9FD34823293D06E800DB0EE9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9FD34822293D06E800DB0EE9 /* Assets.xcassets */; };
|
||||
9FD542E72962D2FF0045321A /* Lists in Frameworks */ = {isa = PBXBuildFile; productRef = 9FD542E62962D2FF0045321A /* Lists */; };
|
||||
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FE151A5293C90F900E9683D /* IconSelectorView.swift */; };
|
||||
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE3DB56296FEFCA00628CB0 /* AppAccount */; };
|
||||
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, maccatalyst, ); productRef = 9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */; };
|
||||
9FE4CCAD2B4C849F00DA5F13 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE4CCAC2B4C849F00DA5F13 /* GiphyUISDK */; };
|
||||
9FE6A42E2BD043A90055D388 /* RevenueCat in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE6A42D2BD043A90055D388 /* RevenueCat */; };
|
||||
9FF2FB622BE7F5D5001560CE /* HashtagPostsWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB602BE7F5A7001560CE /* HashtagPostsWidget.swift */; };
|
||||
9FF2FB632BE7F5D9001560CE /* HashtagPostsWidgetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB5E2BE7F56F001560CE /* HashtagPostsWidgetConfiguration.swift */; };
|
||||
9FF2FB672BE7F816001560CE /* PostsWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB652BE7F805001560CE /* PostsWidgetView.swift */; };
|
||||
9FF2FB6A2BE7F84E001560CE /* SharedUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB682BE7F842001560CE /* SharedUtils.swift */; };
|
||||
9FF2FB702BE8AE9D001560CE /* MentionWidgetConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB6E2BE8AE9B001560CE /* MentionWidgetConfiguration.swift */; };
|
||||
9FF2FB712BE8AEA0001560CE /* MentionWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FF2FB6C2BE8AE90001560CE /* MentionWidget.swift */; };
|
||||
9FFF677C299B7B2C00FE700A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677B299B7B2C00FE700A /* Notifications */; };
|
||||
9FFF677E299B7D2800FE700A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677D299B7D2800FE700A /* Status */; };
|
||||
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677F299B7D2B00FE700A /* DesignSystem */; };
|
||||
9FFF6782299B7D3A00FE700A /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF6781299B7D3A00FE700A /* Account */; };
|
||||
C9B22677297F6C2E001F9EFE /* ContentSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9B22676297F6C2E001F9EFE /* ContentSettingsView.swift */; };
|
||||
|
@ -117,6 +156,13 @@
|
|||
remoteGlobalIDString = 9F2A5415296AB631009B2D7C;
|
||||
remoteInfo = IceCubesNotifications;
|
||||
};
|
||||
9F7788D42BE652B2004E6BEF /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9FBFE631292A715500C250E9 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 9F7788C42BE652B1004E6BEF;
|
||||
remoteInfo = IceCubesAppWidgetsExtensionExtension;
|
||||
};
|
||||
9FAD859029743F7400496AB1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 9FBFE631292A715500C250E9 /* Project object */;
|
||||
|
@ -143,6 +189,7 @@
|
|||
E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */,
|
||||
9F2A541D296AB631009B2D7C /* IceCubesNotifications.appex in Embed Foundation Extensions */,
|
||||
9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */,
|
||||
9F7788D62BE652B2004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex in Embed Foundation Extensions */,
|
||||
);
|
||||
name = "Embed Foundation Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -187,11 +234,15 @@
|
|||
9F2B92F5295AE04800DE16D0 /* Tabs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
|
||||
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAccountsView.swift; sourceTree = "<group>"; };
|
||||
9F2B92FB295DA94500DE16D0 /* InstanceInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceInfoView.swift; sourceTree = "<group>"; };
|
||||
9F35DB42294F9A2900B3281A /* Status */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Status; path = Packages/Status; sourceTree = "<group>"; };
|
||||
9F35DB45294FA04C00B3281A /* DesignSystem */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DesignSystem; path = Packages/DesignSystem; sourceTree = "<group>"; };
|
||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTab.swift; sourceTree = "<group>"; };
|
||||
9F35DB4829506F7F00B3281A /* Notifications */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Notifications; path = Packages/Notifications; sourceTree = "<group>"; };
|
||||
9F35DB4B2952005C00B3281A /* MessagesTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesTab.swift; sourceTree = "<group>"; };
|
||||
9F37BDDA2BE36E22007F28AD /* PostIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostIntent.swift; sourceTree = "<group>"; };
|
||||
9F37BDDC2BE37193007F28AD /* AppIntentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIntentService.swift; sourceTree = "<group>"; };
|
||||
9F37BDDE2BE37C35007F28AD /* TabIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabIntent.swift; sourceTree = "<group>"; };
|
||||
9F37BDE02BE38646007F28AD /* PostImageIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostImageIntent.swift; sourceTree = "<group>"; };
|
||||
9F37BDE22BE393A7007F28AD /* AppShortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShortcuts.swift; sourceTree = "<group>"; };
|
||||
9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
|
||||
9F398AA32935F90100A889F2 /* Models */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Models; path = Packages/Models; sourceTree = "<group>"; };
|
||||
9F398AA52935FE8A00A889F2 /* AppRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRegistry.swift; sourceTree = "<group>"; };
|
||||
|
@ -200,6 +251,9 @@
|
|||
9F4A48182976B21900A1A038 /* ProfileTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTab.swift; sourceTree = "<group>"; };
|
||||
9F55C68C2955968700F94077 /* ExploreTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreTab.swift; sourceTree = "<group>"; };
|
||||
9F55C68E295598F900F94077 /* Explore */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Explore; path = Packages/Explore; sourceTree = "<group>"; };
|
||||
9F5BE6212BF48FBA0074387E /* ListsWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListsWidget.swift; sourceTree = "<group>"; };
|
||||
9F5BE6232BF48FC40074387E /* ListsWidgetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListsWidgetConfiguration.swift; sourceTree = "<group>"; };
|
||||
9F5BE6252BF48FE10074387E /* ListEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListEntity.swift; sourceTree = "<group>"; };
|
||||
9F5E581729545B5500A53960 /* Env */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Env; path = Packages/Env; sourceTree = "<group>"; };
|
||||
9F6028552B3F36AE00476078 /* AppView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppView.swift; sourceTree = "<group>"; };
|
||||
9F6028572B3F3B7600476078 /* ToolbarTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarTab.swift; sourceTree = "<group>"; };
|
||||
|
@ -210,10 +264,24 @@
|
|||
9F7335EE29674F7100AFF0BA /* QuickLook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickLook.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS16.2.sdk/System/Library/Frameworks/QuickLook.framework; sourceTree = DEVELOPER_DIR; };
|
||||
9F7335F12967608F00AFF0BA /* AddRemoteTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddRemoteTimelineView.swift; sourceTree = "<group>"; };
|
||||
9F7335F82968576500AFF0BA /* DisplaySettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplaySettingsView.swift; sourceTree = "<group>"; };
|
||||
9F7788BF2BE63935004E6BEF /* InlinePostIntent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InlinePostIntent.swift; sourceTree = "<group>"; };
|
||||
9F7788C52BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = IceCubesAppWidgetsExtensionExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9F7788C62BE652B1004E6BEF /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; };
|
||||
9F7788C82BE652B1004E6BEF /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; };
|
||||
9F7788CB2BE652B1004E6BEF /* IceCubesAppWidgetsExtensionBundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesAppWidgetsExtensionBundle.swift; sourceTree = "<group>"; };
|
||||
9F7788CD2BE652B1004E6BEF /* LatestPostsWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestPostsWidget.swift; sourceTree = "<group>"; };
|
||||
9F7788CF2BE652B1004E6BEF /* LatestPostsWidgetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatestPostsWidgetConfiguration.swift; sourceTree = "<group>"; };
|
||||
9F7788D12BE652B2004E6BEF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
9F7788D32BE652B2004E6BEF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
9F7788D72BE652B2004E6BEF /* IceCubesAppWidgetsExtensionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesAppWidgetsExtensionExtension.entitlements; sourceTree = "<group>"; };
|
||||
9F7788E72BE65533004E6BEF /* AppAccountEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppAccountEntity.swift; sourceTree = "<group>"; };
|
||||
9F7788EC2BE78D75004E6BEF /* TimelineFilterEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineFilterEntity.swift; sourceTree = "<group>"; };
|
||||
9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "IceCubesApp-release.xcconfig"; sourceTree = "<group>"; };
|
||||
9F7D939929805DBD00EE6B7A /* AccountSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountSettingView.swift; sourceTree = "<group>"; };
|
||||
9F8B920E2BF77DB4003D37A2 /* AccountWidgetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWidgetConfiguration.swift; sourceTree = "<group>"; };
|
||||
9F8B92102BF77DBB003D37A2 /* AccountWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWidget.swift; sourceTree = "<group>"; };
|
||||
9F8B92142BF77F05003D37A2 /* AccountWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountWidgetView.swift; sourceTree = "<group>"; };
|
||||
9FA6FD6129C04A8800E2312C /* TranslationSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TranslationSettingsView.swift; sourceTree = "<group>"; };
|
||||
9FAD85822971BF7200496AB1 /* Secret.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Secret.plist; sourceTree = "<group>"; };
|
||||
9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = IceCubesShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9FAD858A29743F7400496AB1 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
|
@ -223,8 +291,13 @@
|
|||
9FAE4ACA293783B000772766 /* SettingsTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsTab.swift; sourceTree = "<group>"; };
|
||||
9FB183212AE9268800BBB692 /* IceCubesApp+Menu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Menu.swift"; sourceTree = "<group>"; };
|
||||
9FB183282AE9449100BBB692 /* IceCubesApp+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IceCubesApp+Scene.swift"; sourceTree = "<group>"; };
|
||||
9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarEntriesSettingsView.swift; sourceTree = "<group>"; };
|
||||
9FBFE639292A715500C250E9 /* Ice Cubes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Ice Cubes.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9FBFE63C292A715500C250E9 /* IceCubesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IceCubesApp.swift; sourceTree = "<group>"; };
|
||||
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsGroupSettingView.swift; sourceTree = "<group>"; };
|
||||
9FC14EF32B494D940006CEE1 /* RemoteTimelinesSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteTimelinesSettingView.swift; sourceTree = "<group>"; };
|
||||
9FC14EF52B494DFF0006CEE1 /* RecenTagsSettingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecenTagsSettingView.swift; sourceTree = "<group>"; };
|
||||
9FC2A3892B49D10000DFD1C1 /* StatusKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = StatusKit; path = Packages/StatusKit; sourceTree = "<group>"; };
|
||||
9FC60CB82AE6C2F600C6EAD2 /* IceCubesActionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IceCubesActionExtension.entitlements; sourceTree = "<group>"; };
|
||||
9FCBB3D22984EFD5009B77EE /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
9FCBB3D429859615009B77EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
|
@ -233,6 +306,12 @@
|
|||
9FE0346A2ADD59AC00529EA8 /* MediaUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = MediaUI; path = Packages/MediaUI; sourceTree = "<group>"; };
|
||||
9FE151A5293C90F900E9683D /* IconSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconSelectorView.swift; sourceTree = "<group>"; };
|
||||
9FE3DB55296FEF5800628CB0 /* AppAccount */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = AppAccount; path = Packages/AppAccount; sourceTree = "<group>"; };
|
||||
9FF2FB5E2BE7F56F001560CE /* HashtagPostsWidgetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagPostsWidgetConfiguration.swift; sourceTree = "<group>"; };
|
||||
9FF2FB602BE7F5A7001560CE /* HashtagPostsWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagPostsWidget.swift; sourceTree = "<group>"; };
|
||||
9FF2FB652BE7F805001560CE /* PostsWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostsWidgetView.swift; sourceTree = "<group>"; };
|
||||
9FF2FB682BE7F842001560CE /* SharedUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedUtils.swift; sourceTree = "<group>"; };
|
||||
9FF2FB6C2BE8AE90001560CE /* MentionWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionWidget.swift; sourceTree = "<group>"; };
|
||||
9FF2FB6E2BE8AE9B001560CE /* MentionWidgetConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionWidgetConfiguration.swift; sourceTree = "<group>"; };
|
||||
B0BAB49E29B3D7A9008F54D7 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
C4CBB90B298A0DA3007E1707 /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
C4FBCF6F298FD88A0015DF22 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
|
@ -262,12 +341,27 @@
|
|||
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */,
|
||||
9F2A5428296AB683009B2D7C /* Models in Frameworks */,
|
||||
9FFF6782299B7D3A00FE700A /* Account in Frameworks */,
|
||||
9FC2A38D2B49D1A200DFD1C1 /* StatusKit in Frameworks */,
|
||||
9F2A5426296AB67E009B2D7C /* KeychainSwift in Frameworks */,
|
||||
9FFF677E299B7D2800FE700A /* Status in Frameworks */,
|
||||
9F2A5424296AB67A009B2D7C /* Env in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9F7788C22BE652B1004E6BEF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9F7788E42BE6543D004E6BEF /* Models in Frameworks */,
|
||||
9F7788E62BE6543D004E6BEF /* Network in Frameworks */,
|
||||
9F7788E02BE6543D004E6BEF /* AppAccount in Frameworks */,
|
||||
9F7788DE2BE6543D004E6BEF /* Account in Frameworks */,
|
||||
9F7788E22BE6543D004E6BEF /* Env in Frameworks */,
|
||||
9F7788C92BE652B1004E6BEF /* SwiftUI.framework in Frameworks */,
|
||||
9F7788C72BE652B1004E6BEF /* WidgetKit.framework in Frameworks */,
|
||||
9F7788F02BE78E77004E6BEF /* Timeline in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9FAD858529743F7400496AB1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -275,10 +369,11 @@
|
|||
9FAD85A2297456A400496AB1 /* Env in Frameworks */,
|
||||
9FAD85A0297456A100496AB1 /* Models in Frameworks */,
|
||||
9FAD85A4297456A800496AB1 /* DesignSystem in Frameworks */,
|
||||
9FE4CCAD2B4C849F00DA5F13 /* GiphyUISDK in Frameworks */,
|
||||
9FAD859E2974569B00496AB1 /* Account in Frameworks */,
|
||||
9FAD859C2974422700496AB1 /* AppAccount in Frameworks */,
|
||||
9FC2A38F2B49D1AA00DFD1C1 /* StatusKit in Frameworks */,
|
||||
9FAD859A297440CB00496AB1 /* KeychainSwift in Frameworks */,
|
||||
9FAD85982974405D00496AB1 /* Status in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -287,8 +382,8 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */,
|
||||
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */,
|
||||
9F7335ED2967463400AFF0BA /* AVKit.framework in Frameworks */,
|
||||
9F2A540C29699705009B2D7C /* RevenueCat in Frameworks */,
|
||||
9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */,
|
||||
9F55C6902955993C00F94077 /* Explore in Frameworks */,
|
||||
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */,
|
||||
|
@ -299,11 +394,11 @@
|
|||
9FD542E72962D2FF0045321A /* Lists in Frameworks */,
|
||||
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */,
|
||||
9F5E581929545BE700A53960 /* Env in Frameworks */,
|
||||
9F2A540A29699705009B2D7C /* ReceiptParser in Frameworks */,
|
||||
9F35DB44294F9A7D00B3281A /* Status in Frameworks */,
|
||||
DA0B24FB2A6876D50045BDD7 /* SFSafeSymbols in Frameworks */,
|
||||
9FE6A42E2BD043A90055D388 /* RevenueCat in Frameworks */,
|
||||
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
|
||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */,
|
||||
9FC2A38B2B49D19A00DFD1C1 /* StatusKit in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -339,6 +434,22 @@
|
|||
path = IceCubesNotifications;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F37BDD92BE36E08007F28AD /* IceCubesAppIntents */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9F7788E72BE65533004E6BEF /* AppAccountEntity.swift */,
|
||||
9F37BDDC2BE37193007F28AD /* AppIntentService.swift */,
|
||||
9F37BDE22BE393A7007F28AD /* AppShortcuts.swift */,
|
||||
9F7788BF2BE63935004E6BEF /* InlinePostIntent.swift */,
|
||||
9F37BDE02BE38646007F28AD /* PostImageIntent.swift */,
|
||||
9F37BDDA2BE36E22007F28AD /* PostIntent.swift */,
|
||||
9F37BDDE2BE37C35007F28AD /* TabIntent.swift */,
|
||||
9F7788EC2BE78D75004E6BEF /* TimelineFilterEntity.swift */,
|
||||
9F5BE6252BF48FE10074387E /* ListEntity.swift */,
|
||||
);
|
||||
path = IceCubesAppIntents;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F398AB429360A5800A889F2 /* App */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -363,6 +474,15 @@
|
|||
path = Resources;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F5BE6202BF48FB20074387E /* ListsWidget */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9F5BE6212BF48FBA0074387E /* ListsWidget.swift */,
|
||||
9F5BE6232BF48FC40074387E /* ListsWidgetConfiguration.swift */,
|
||||
);
|
||||
path = ListsWidget;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F654BF0299AC46200D27FA5 /* Report */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -380,6 +500,33 @@
|
|||
path = Timeline;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F7788CA2BE652B1004E6BEF /* IceCubesAppWidgetsExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9F8B920D2BF77DA8003D37A2 /* AccountWidget */,
|
||||
9F5BE6202BF48FB20074387E /* ListsWidget */,
|
||||
9FF2FB6B2BE8AE78001560CE /* MentionWidget */,
|
||||
9FF2FB642BE7F7FA001560CE /* Shared */,
|
||||
9FF2FB5D2BE7F559001560CE /* HashtagPostsWidget */,
|
||||
9FF2FB5C2BE7F549001560CE /* LatestPostsWidget */,
|
||||
9F7788D72BE652B2004E6BEF /* IceCubesAppWidgetsExtensionExtension.entitlements */,
|
||||
9F7788CB2BE652B1004E6BEF /* IceCubesAppWidgetsExtensionBundle.swift */,
|
||||
9F7788D12BE652B2004E6BEF /* Assets.xcassets */,
|
||||
9F7788D32BE652B2004E6BEF /* Info.plist */,
|
||||
);
|
||||
path = IceCubesAppWidgetsExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9F8B920D2BF77DA8003D37A2 /* AccountWidget */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9F8B920E2BF77DB4003D37A2 /* AccountWidgetConfiguration.swift */,
|
||||
9F8B92102BF77DBB003D37A2 /* AccountWidget.swift */,
|
||||
9F8B92142BF77F05003D37A2 /* AccountWidgetView.swift */,
|
||||
);
|
||||
path = AccountWidget;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9FA0D2AC29921C1F008A143B /* Embeds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -444,9 +591,11 @@
|
|||
DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */,
|
||||
9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */,
|
||||
9FBFE63B292A715500C250E9 /* IceCubesApp */,
|
||||
9F37BDD92BE36E08007F28AD /* IceCubesAppIntents */,
|
||||
E9DF41FD29830FEC0003AAD2 /* IceCubesActionExtension */,
|
||||
9F2A5417296AB631009B2D7C /* IceCubesNotifications */,
|
||||
9FAD858929743F7400496AB1 /* IceCubesShareExtension */,
|
||||
9F7788CA2BE652B1004E6BEF /* IceCubesAppWidgetsExtension */,
|
||||
9FBFE63A292A715500C250E9 /* Products */,
|
||||
9FBFE64C292A72BD00C250E9 /* Frameworks */,
|
||||
9FE3DB55296FEF5800628CB0 /* AppAccount */,
|
||||
|
@ -456,12 +605,12 @@
|
|||
9F55C68E295598F900F94077 /* Explore */,
|
||||
9F5E581729545B5500A53960 /* Env */,
|
||||
9F398AA32935F90100A889F2 /* Models */,
|
||||
9FC2A3892B49D10000DFD1C1 /* StatusKit */,
|
||||
9FE0346A2ADD59AC00529EA8 /* MediaUI */,
|
||||
9F29553D292B67B600E0E81B /* Network */,
|
||||
9FD542E52962D2CE0045321A /* Lists */,
|
||||
9F35DB4829506F7F00B3281A /* Notifications */,
|
||||
9F29553E292B6AF600E0E81B /* Timeline */,
|
||||
9F35DB42294F9A2900B3281A /* Status */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
|
@ -472,6 +621,7 @@
|
|||
9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */,
|
||||
9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */,
|
||||
E9DF41FA29830FEC0003AAD2 /* IceCubesActionExtension.appex */,
|
||||
9F7788C52BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -484,7 +634,6 @@
|
|||
9FAE4AC8293774FF00772766 /* Info.plist */,
|
||||
9F398AB429360A5800A889F2 /* App */,
|
||||
9F398AB529360A6100A889F2 /* Resources */,
|
||||
9FAD85822971BF7200496AB1 /* Secret.plist */,
|
||||
);
|
||||
path = IceCubesApp;
|
||||
sourceTree = "<group>";
|
||||
|
@ -497,6 +646,8 @@
|
|||
9F7335EE29674F7100AFF0BA /* QuickLook.framework */,
|
||||
9F7335EB2967461B00AFF0BA /* AVKit.framework */,
|
||||
E9DF41FB29830FEC0003AAD2 /* UniformTypeIdentifiers.framework */,
|
||||
9F7788C62BE652B1004E6BEF /* WidgetKit.framework */,
|
||||
9F7788C82BE652B1004E6BEF /* SwiftUI.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
@ -518,10 +669,50 @@
|
|||
D08A9C3429956CFA00204A4A /* SwipeActionsSettingsView.swift */,
|
||||
9FA6FD6129C04A8800E2312C /* TranslationSettingsView.swift */,
|
||||
9F15D6012B3D6E280008C220 /* TabbarEntriesSettingsView.swift */,
|
||||
9FC14EF12B494D180006CEE1 /* TagsGroupSettingView.swift */,
|
||||
9FC14EF32B494D940006CEE1 /* RemoteTimelinesSettingView.swift */,
|
||||
9FC14EF52B494DFF0006CEE1 /* RecenTagsSettingView.swift */,
|
||||
9FBA1D342B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift */,
|
||||
);
|
||||
path = Settings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9FF2FB5C2BE7F549001560CE /* LatestPostsWidget */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9F7788CD2BE652B1004E6BEF /* LatestPostsWidget.swift */,
|
||||
9F7788CF2BE652B1004E6BEF /* LatestPostsWidgetConfiguration.swift */,
|
||||
);
|
||||
path = LatestPostsWidget;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9FF2FB5D2BE7F559001560CE /* HashtagPostsWidget */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9FF2FB5E2BE7F56F001560CE /* HashtagPostsWidgetConfiguration.swift */,
|
||||
9FF2FB602BE7F5A7001560CE /* HashtagPostsWidget.swift */,
|
||||
);
|
||||
path = HashtagPostsWidget;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9FF2FB642BE7F7FA001560CE /* Shared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9FF2FB652BE7F805001560CE /* PostsWidgetView.swift */,
|
||||
9FF2FB682BE7F842001560CE /* SharedUtils.swift */,
|
||||
);
|
||||
path = Shared;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9FF2FB6B2BE8AE78001560CE /* MentionWidget */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9FF2FB6C2BE8AE90001560CE /* MentionWidget.swift */,
|
||||
9FF2FB6E2BE8AE9B001560CE /* MentionWidgetConfiguration.swift */,
|
||||
);
|
||||
path = MentionWidget;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E9B576C029743F2A00BCE646 /* Localization */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -565,14 +756,39 @@
|
|||
9F2A5427296AB683009B2D7C /* Models */,
|
||||
9F7D93932980063100EE6B7A /* AppAccount */,
|
||||
9FFF677B299B7B2C00FE700A /* Notifications */,
|
||||
9FFF677D299B7D2800FE700A /* Status */,
|
||||
9FFF677F299B7D2B00FE700A /* DesignSystem */,
|
||||
9FFF6781299B7D3A00FE700A /* Account */,
|
||||
9FC2A38C2B49D1A200DFD1C1 /* StatusKit */,
|
||||
);
|
||||
productName = IceCubesNotifications;
|
||||
productReference = 9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
9F7788C42BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9F7788D82BE652B2004E6BEF /* Build configuration list for PBXNativeTarget "IceCubesAppWidgetsExtensionExtension" */;
|
||||
buildPhases = (
|
||||
9F7788C12BE652B1004E6BEF /* Sources */,
|
||||
9F7788C22BE652B1004E6BEF /* Frameworks */,
|
||||
9F7788C32BE652B1004E6BEF /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = IceCubesAppWidgetsExtensionExtension;
|
||||
packageProductDependencies = (
|
||||
9F7788DD2BE6543D004E6BEF /* Account */,
|
||||
9F7788DF2BE6543D004E6BEF /* AppAccount */,
|
||||
9F7788E12BE6543D004E6BEF /* Env */,
|
||||
9F7788E32BE6543D004E6BEF /* Models */,
|
||||
9F7788E52BE6543D004E6BEF /* Network */,
|
||||
9F7788EF2BE78E77004E6BEF /* Timeline */,
|
||||
);
|
||||
productName = IceCubesAppWidgetsExtensionExtension;
|
||||
productReference = 9F7788C52BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
9FAD858729743F7400496AB1 /* IceCubesShareExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 9FAD859329743F7400496AB1 /* Build configuration list for PBXNativeTarget "IceCubesShareExtension" */;
|
||||
|
@ -587,13 +803,14 @@
|
|||
);
|
||||
name = IceCubesShareExtension;
|
||||
packageProductDependencies = (
|
||||
9FAD85972974405D00496AB1 /* Status */,
|
||||
9FAD8599297440CB00496AB1 /* KeychainSwift */,
|
||||
9FAD859B2974422700496AB1 /* AppAccount */,
|
||||
9FAD859D2974569B00496AB1 /* Account */,
|
||||
9FAD859F297456A100496AB1 /* Models */,
|
||||
9FAD85A1297456A400496AB1 /* Env */,
|
||||
9FAD85A3297456A800496AB1 /* DesignSystem */,
|
||||
9FC2A38E2B49D1AA00DFD1C1 /* StatusKit */,
|
||||
9FE4CCAC2B4C849F00DA5F13 /* GiphyUISDK */,
|
||||
);
|
||||
productName = IceCubesShareExtension;
|
||||
productReference = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */;
|
||||
|
@ -614,6 +831,7 @@
|
|||
9F2A541C296AB631009B2D7C /* PBXTargetDependency */,
|
||||
9FAD859129743F7400496AB1 /* PBXTargetDependency */,
|
||||
E9DF420629830FEC0003AAD2 /* PBXTargetDependency */,
|
||||
9F7788D52BE652B2004E6BEF /* PBXTargetDependency */,
|
||||
);
|
||||
name = IceCubesApp;
|
||||
packageProductDependencies = (
|
||||
|
@ -622,16 +840,16 @@
|
|||
9F398AA82935FFDB00A889F2 /* Account */,
|
||||
9F398AAA2935FFDB00A889F2 /* Models */,
|
||||
9FAE4ACD29379A5A00772766 /* KeychainSwift */,
|
||||
9F35DB43294F9A7D00B3281A /* Status */,
|
||||
9F35DB4929506FA100B3281A /* Notifications */,
|
||||
9F5E581829545BE700A53960 /* Env */,
|
||||
9F55C68F2955993C00F94077 /* Explore */,
|
||||
9FD542E62962D2FF0045321A /* Lists */,
|
||||
9F7335E92966B3F800AFF0BA /* Conversations */,
|
||||
9F2A540929699705009B2D7C /* ReceiptParser */,
|
||||
9F2A540B29699705009B2D7C /* RevenueCat */,
|
||||
9FE3DB56296FEFCA00628CB0 /* AppAccount */,
|
||||
DA0B24FA2A6876D50045BDD7 /* SFSafeSymbols */,
|
||||
9FC2A38A2B49D19A00DFD1C1 /* StatusKit */,
|
||||
9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */,
|
||||
9FE6A42D2BD043A90055D388 /* RevenueCat */,
|
||||
);
|
||||
productName = IceCubesApp;
|
||||
productReference = 9FBFE639292A715500C250E9 /* Ice Cubes.app */;
|
||||
|
@ -665,12 +883,15 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1420;
|
||||
LastSwiftUpdateCheck = 1530;
|
||||
LastUpgradeCheck = 1500;
|
||||
TargetAttributes = {
|
||||
9F2A5415296AB631009B2D7C = {
|
||||
CreatedOnToolsVersion = 14.2;
|
||||
};
|
||||
9F7788C42BE652B1004E6BEF = {
|
||||
CreatedOnToolsVersion = 15.3;
|
||||
};
|
||||
9FAD858729743F7400496AB1 = {
|
||||
CreatedOnToolsVersion = 14.2;
|
||||
};
|
||||
|
@ -711,8 +932,9 @@
|
|||
mainGroup = 9FBFE630292A715500C250E9;
|
||||
packageReferences = (
|
||||
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */,
|
||||
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
||||
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
||||
9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */,
|
||||
9FE6A42C2BD043A80055D388 /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
||||
);
|
||||
productRefGroup = 9FBFE63A292A715500C250E9 /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -722,6 +944,7 @@
|
|||
E9DF41F929830FEC0003AAD2 /* IceCubesActionExtension */,
|
||||
9F2A5415296AB631009B2D7C /* IceCubesNotifications */,
|
||||
9FAD858729743F7400496AB1 /* IceCubesShareExtension */,
|
||||
9F7788C42BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -737,6 +960,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9F7788C32BE652B1004E6BEF /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9F7788D22BE652B2004E6BEF /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9FAD858629743F7400496AB1 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -760,7 +991,6 @@
|
|||
9F18801829AE477F00D85459 /* favorite.wav in Resources */,
|
||||
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */,
|
||||
069709A8298C87B5006E4CB5 /* OpenDyslexic-Regular.otf in Resources */,
|
||||
9FAD85832971BF7200496AB1 /* Secret.plist in Resources */,
|
||||
9F18801229AE477F00D85459 /* tabSelection.wav in Resources */,
|
||||
9F18801429AE477F00D85459 /* bookmark.wav in Resources */,
|
||||
9F18801629AE477F00D85459 /* refresh.wav in Resources */,
|
||||
|
@ -791,6 +1021,30 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9F7788C12BE652B1004E6BEF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9F5BE6272BF492CF0074387E /* ListEntity.swift in Sources */,
|
||||
9FF2FB622BE7F5D5001560CE /* HashtagPostsWidget.swift in Sources */,
|
||||
9FF2FB712BE8AEA0001560CE /* MentionWidget.swift in Sources */,
|
||||
9F8B92162BF77F0B003D37A2 /* AccountWidgetView.swift in Sources */,
|
||||
9F8B92122BF77DBE003D37A2 /* AccountWidgetConfiguration.swift in Sources */,
|
||||
9F8B92132BF77DBE003D37A2 /* AccountWidget.swift in Sources */,
|
||||
9F7788EA2BE65585004E6BEF /* AppAccountEntity.swift in Sources */,
|
||||
9FF2FB6A2BE7F84E001560CE /* SharedUtils.swift in Sources */,
|
||||
9F7788CE2BE652B1004E6BEF /* LatestPostsWidget.swift in Sources */,
|
||||
9F7788EE2BE78D7B004E6BEF /* TimelineFilterEntity.swift in Sources */,
|
||||
9F5BE6292BF492D40074387E /* ListsWidget.swift in Sources */,
|
||||
9F7788CC2BE652B1004E6BEF /* IceCubesAppWidgetsExtensionBundle.swift in Sources */,
|
||||
9FF2FB702BE8AE9D001560CE /* MentionWidgetConfiguration.swift in Sources */,
|
||||
9F7788D02BE652B1004E6BEF /* LatestPostsWidgetConfiguration.swift in Sources */,
|
||||
9FF2FB672BE7F816001560CE /* PostsWidgetView.swift in Sources */,
|
||||
9FF2FB632BE7F5D9001560CE /* HashtagPostsWidgetConfiguration.swift in Sources */,
|
||||
9F5BE6282BF492D10074387E /* ListsWidgetConfiguration.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9FAD858429743F7400496AB1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -812,8 +1066,15 @@
|
|||
9F15D6042B3DC2180008C220 /* NavigationSheet.swift in Sources */,
|
||||
9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */,
|
||||
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */,
|
||||
9F37BDDB2BE36E22007F28AD /* PostIntent.swift in Sources */,
|
||||
9F37BDDD2BE37193007F28AD /* AppIntentService.swift in Sources */,
|
||||
9F37BDE12BE38646007F28AD /* PostImageIntent.swift in Sources */,
|
||||
9F37BDDF2BE37C35007F28AD /* TabIntent.swift in Sources */,
|
||||
9F7788C02BE63935004E6BEF /* InlinePostIntent.swift in Sources */,
|
||||
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */,
|
||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */,
|
||||
9FC14EF22B494D180006CEE1 /* TagsGroupSettingView.swift in Sources */,
|
||||
9F15D6022B3D6E280008C220 /* TabbarEntriesSettingsView.swift in Sources */,
|
||||
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */,
|
||||
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */,
|
||||
|
@ -828,12 +1089,17 @@
|
|||
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */,
|
||||
639CDF9C296AC82F00C35E58 /* SafariRouter.swift in Sources */,
|
||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */,
|
||||
9F7788ED2BE78D75004E6BEF /* TimelineFilterEntity.swift in Sources */,
|
||||
9F37BDE32BE393A7007F28AD /* AppShortcuts.swift in Sources */,
|
||||
9F654BEF299AC45B00D27FA5 /* ReportView.swift in Sources */,
|
||||
D08A9C3529956CFA00204A4A /* SwipeActionsSettingsView.swift in Sources */,
|
||||
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */,
|
||||
9F7788E82BE65533004E6BEF /* AppAccountEntity.swift in Sources */,
|
||||
9FC14EF62B494DFF0006CEE1 /* RecenTagsSettingView.swift in Sources */,
|
||||
9F6028562B3F36AE00476078 /* AppView.swift in Sources */,
|
||||
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
|
||||
9F1E8B47298EBCBB00609F80 /* HapticSettingsView.swift in Sources */,
|
||||
9FBA1D352B4E9B7E00ADB568 /* SidebarEntriesSettingsView.swift in Sources */,
|
||||
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */,
|
||||
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */,
|
||||
);
|
||||
|
@ -855,6 +1121,15 @@
|
|||
target = 9F2A5415296AB631009B2D7C /* IceCubesNotifications */;
|
||||
targetProxy = 9F2A541B296AB631009B2D7C /* PBXContainerItemProxy */;
|
||||
};
|
||||
9F7788D52BE652B2004E6BEF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilters = (
|
||||
ios,
|
||||
maccatalyst,
|
||||
);
|
||||
target = 9F7788C42BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension */;
|
||||
targetProxy = 9F7788D42BE652B2004E6BEF /* PBXContainerItemProxy */;
|
||||
};
|
||||
9FAD859129743F7400496AB1 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
platformFilters = (
|
||||
|
@ -918,7 +1193,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -953,7 +1228,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -969,6 +1244,78 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
9F7788D92BE652B2004E6BEF /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CODE_SIGN_ENTITLEMENTS = IceCubesAppWidgetsExtension/IceCubesAppWidgetsExtensionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesAppWidgetsExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
9F7788DA2BE652B2004E6BEF /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground;
|
||||
CODE_SIGN_ENTITLEMENTS = IceCubesAppWidgetsExtension/IceCubesAppWidgetsExtensionExtension.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = "$(DEVELOPMENT_TEAM)";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesAppWidgetsExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SUPPORTS_MACCATALYST = YES;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
9FAD859429743F7400496AB1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -989,7 +1336,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1023,7 +1370,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1167,10 +1514,11 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate0 AppIconAlternate1 AppIconAlternate2 AppIconAlternate3 AppIconAlternate4 AppIconAlternate5 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate9 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40 AppIconAlternate42 AppIconAlternate41 AppIconAlternate45 AppIconAlternate44 AppIconAlternate47 AppIconAlternate49 AppIconAlternate51 AppIconAlternate48 AppIconAlternate46 AppIconAlternate50 AppIconAlternate43";
|
||||
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate0 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40 AppIconAlternate42 AppIconAlternate2 AppIconAlternate41 AppIconAlternate45 AppIconAlternate44 AppIconAlternate1 AppIconAlternate4 AppIconAlternate3 AppIconAlternate5 AppIconAlternate46 AppIconAlternate9 AppIconAlternate43";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/App/IceCubesApp.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
|
@ -1186,7 +1534,8 @@
|
|||
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to attach to your Mastodon posts.";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "© 2024 Thomas Ricouard";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
|
@ -1203,7 +1552,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
||||
PRODUCT_NAME = "Ice Cubes";
|
||||
SDKROOT = auto;
|
||||
|
@ -1221,10 +1570,11 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate0 AppIconAlternate1 AppIconAlternate2 AppIconAlternate3 AppIconAlternate4 AppIconAlternate5 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate9 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40 AppIconAlternate42 AppIconAlternate41 AppIconAlternate45 AppIconAlternate44 AppIconAlternate47 AppIconAlternate49 AppIconAlternate51 AppIconAlternate48 AppIconAlternate46 AppIconAlternate50 AppIconAlternate43";
|
||||
ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = "AppIconAlternate0 AppIconAlternate6 AppIconAlternate7 AppIconAlternate8 AppIconAlternate10 AppIconAlternate11 AppIconAlternate12 AppIconAlternate13 AppIconAlternate14 AppIconAlternate15 AppIconAlternate16 AppIconAlternate17 AppIconAlternate19 AppIconAlternate18 AppIconAlternate20 AppIconAlternate21 AppIconAlternate22 AppIconAlternate23 AppIconAlternate24 AppIconAlternate25 AppIconAlternate26 AppIconAlternate27 AppIconAlternate28 AppIconAlternate29 AppIconAlternate30 AppIconAlternate31 AppIconAlternate32 AppIconAlternate33 AppIconAlternate34 AppIconAlternate35 AppIconAlternate36 AppIconAlternate37 AppIconAlternate38 AppIconAlternate39 AppIconAlternate40 AppIconAlternate42 AppIconAlternate2 AppIconAlternate41 AppIconAlternate45 AppIconAlternate44 AppIconAlternate1 AppIconAlternate4 AppIconAlternate3 AppIconAlternate5 AppIconAlternate46 AppIconAlternate9 AppIconAlternate43";
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO;
|
||||
CODE_SIGN_ENTITLEMENTS = "IceCubesApp/App/IceCubesApp-release.entitlements";
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||
|
@ -1240,7 +1590,8 @@
|
|||
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to Mastodon";
|
||||
INFOPLIST_KEY_NSCameraUsageDescription = "Upload photos & videos to attach to your Mastodon posts.";
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "© 2024 Thomas Ricouard";
|
||||
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
|
||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||
|
@ -1257,7 +1608,7 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
||||
PRODUCT_NAME = "Ice Cubes";
|
||||
SDKROOT = auto;
|
||||
|
@ -1292,7 +1643,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1327,7 +1678,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.10.8;
|
||||
MARKETING_VERSION = 1.10.41;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -1354,6 +1705,15 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9F7788D82BE652B2004E6BEF /* Build configuration list for PBXNativeTarget "IceCubesAppWidgetsExtensionExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
9F7788D92BE652B2004E6BEF /* Debug */,
|
||||
9F7788DA2BE652B2004E6BEF /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
9FAD859329743F7400496AB1 /* Build configuration list for PBXNativeTarget "IceCubesShareExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
@ -1393,14 +1753,6 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/RevenueCat/purchases-ios.git";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 4.0.0;
|
||||
};
|
||||
};
|
||||
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/evgenyneu/keychain-swift";
|
||||
|
@ -1409,6 +1761,22 @@
|
|||
kind = branch;
|
||||
};
|
||||
};
|
||||
9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/Giphy/giphy-ios-sdk";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 2.2.8;
|
||||
};
|
||||
};
|
||||
9FE6A42C2BD043A80055D388 /* XCRemoteSwiftPackageReference "purchases-ios" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/RevenueCat/purchases-ios";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 4.40.1;
|
||||
};
|
||||
};
|
||||
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/SFSafeSymbols/SFSafeSymbols";
|
||||
|
@ -1424,16 +1792,6 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Timeline;
|
||||
};
|
||||
9F2A540929699705009B2D7C /* ReceiptParser */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */;
|
||||
productName = ReceiptParser;
|
||||
};
|
||||
9F2A540B29699705009B2D7C /* RevenueCat */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */;
|
||||
productName = RevenueCat;
|
||||
};
|
||||
9F2A5423296AB67A009B2D7C /* Env */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Env;
|
||||
|
@ -1447,10 +1805,6 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Models;
|
||||
};
|
||||
9F35DB43294F9A7D00B3281A /* Status */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Status;
|
||||
};
|
||||
9F35DB4929506FA100B3281A /* Notifications */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Notifications;
|
||||
|
@ -1475,13 +1829,33 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Conversations;
|
||||
};
|
||||
9F7D93932980063100EE6B7A /* AppAccount */ = {
|
||||
9F7788DD2BE6543D004E6BEF /* Account */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Account;
|
||||
};
|
||||
9F7788DF2BE6543D004E6BEF /* AppAccount */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = AppAccount;
|
||||
};
|
||||
9FAD85972974405D00496AB1 /* Status */ = {
|
||||
9F7788E12BE6543D004E6BEF /* Env */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Status;
|
||||
productName = Env;
|
||||
};
|
||||
9F7788E32BE6543D004E6BEF /* Models */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Models;
|
||||
};
|
||||
9F7788E52BE6543D004E6BEF /* Network */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Network;
|
||||
};
|
||||
9F7788EF2BE78E77004E6BEF /* Timeline */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Timeline;
|
||||
};
|
||||
9F7D93932980063100EE6B7A /* AppAccount */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = AppAccount;
|
||||
};
|
||||
9FAD8599297440CB00496AB1 /* KeychainSwift */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
|
@ -1517,6 +1891,18 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Network;
|
||||
};
|
||||
9FC2A38A2B49D19A00DFD1C1 /* StatusKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = StatusKit;
|
||||
};
|
||||
9FC2A38C2B49D1A200DFD1C1 /* StatusKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = StatusKit;
|
||||
};
|
||||
9FC2A38E2B49D1AA00DFD1C1 /* StatusKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = StatusKit;
|
||||
};
|
||||
9FD542E62962D2FF0045321A /* Lists */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Lists;
|
||||
|
@ -1525,14 +1911,25 @@
|
|||
isa = XCSwiftPackageProductDependency;
|
||||
productName = AppAccount;
|
||||
};
|
||||
9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
||||
productName = GiphyUISDK;
|
||||
};
|
||||
9FE4CCAC2B4C849F00DA5F13 /* GiphyUISDK */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
||||
productName = GiphyUISDK;
|
||||
};
|
||||
9FE6A42D2BD043A90055D388 /* RevenueCat */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 9FE6A42C2BD043A80055D388 /* XCRemoteSwiftPackageReference "purchases-ios" */;
|
||||
productName = RevenueCat;
|
||||
};
|
||||
9FFF677B299B7B2C00FE700A /* Notifications */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Notifications;
|
||||
};
|
||||
9FFF677D299B7D2800FE700A /* Status */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = Status;
|
||||
};
|
||||
9FFF677F299B7D2B00FE700A /* DesignSystem */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = DesignSystem;
|
||||
|
|
|
@ -9,13 +9,22 @@
|
|||
"version" : "2.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "buttonkit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Dean151/ButtonKit",
|
||||
"state" : {
|
||||
"revision" : "377f5bab4ed047704316d531e0826d4de5ebf6a4",
|
||||
"version" : "0.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "emojitext",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/divadretlaw/EmojiText",
|
||||
"state" : {
|
||||
"revision" : "d0664390e3236ff6241ea0586d80f4e92702973b",
|
||||
"version" : "3.2.1"
|
||||
"revision" : "c54000aa9ccc048619054a5a2da2ce0576ffea18",
|
||||
"version" : "4.0.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -23,8 +32,8 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/Giphy/giphy-ios-sdk",
|
||||
"state" : {
|
||||
"revision" : "95c32b862185e76107841b49bfff8ff7230f3b68",
|
||||
"version" : "2.2.7"
|
||||
"revision" : "9c58a350a3381f1641f5a31cdcd162a406274892",
|
||||
"version" : "2.2.8"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -59,17 +68,17 @@
|
|||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/kean/Nuke",
|
||||
"state" : {
|
||||
"revision" : "1694798e876113d44f6ec6ead965d7286695981d",
|
||||
"version" : "12.2.0"
|
||||
"revision" : "8ecbfc886da39bccb01c34abef5f2ff4073ad633",
|
||||
"version" : "12.4.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "purchases-ios",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/RevenueCat/purchases-ios.git",
|
||||
"location" : "https://github.com/RevenueCat/purchases-ios",
|
||||
"state" : {
|
||||
"revision" : "b8d20ba1c8e13cc73d72e37cf98607d01fd357b6",
|
||||
"version" : "4.31.2"
|
||||
"revision" : "a9763ca482d52ea3d59aa2dfd2fc23427b02dada",
|
||||
"version" : "4.40.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -90,6 +99,24 @@
|
|||
"version" : "0.14.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-cmark",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-cmark.git",
|
||||
"state" : {
|
||||
"revision" : "f218e5d7691f78b55bfa39b367763f4612486c35",
|
||||
"version" : "0.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-markdown",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-markdown",
|
||||
"state" : {
|
||||
"revision" : "e4f95e2dc23097a1a9a1dfdfe3fe3ee44de77378",
|
||||
"version" : "0.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftsoup",
|
||||
"kind" : "remoteSourceControl",
|
||||
|
@ -107,15 +134,6 @@
|
|||
"revision" : "9e1cc02a65b22e09a8251261cccbccce02731fc5",
|
||||
"version" : "1.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swiftui-shimmer",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/markiv/SwiftUI-Shimmer",
|
||||
"state" : {
|
||||
"revision" : "965a7cbcbf094cbcf22b9251a2323bdc3432e171",
|
||||
"version" : "1.1.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1530"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES"
|
||||
buildArchitectures = "Automatic">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9F7788C42BE652B1004E6BEF"
|
||||
BuildableName = "IceCubesAppWidgetsExtensionExtension.appex"
|
||||
BlueprintName = "IceCubesAppWidgetsExtensionExtension"
|
||||
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9FBFE638292A715500C250E9"
|
||||
BuildableName = "Ice Cubes.app"
|
||||
BlueprintName = "IceCubesApp"
|
||||
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9FBFE638292A715500C250E9"
|
||||
BuildableName = "Ice Cubes.app"
|
||||
BlueprintName = "IceCubesApp"
|
||||
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetKind"
|
||||
value = ""
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetDefaultView"
|
||||
value = "timeline"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
<EnvironmentVariable
|
||||
key = "_XCWidgetFamily"
|
||||
value = "systemMedium"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "9FBFE638292A715500C250E9"
|
||||
BuildableName = "Ice Cubes.app"
|
||||
BlueprintName = "IceCubesApp"
|
||||
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -8,7 +8,8 @@ import LinkPresentation
|
|||
import Lists
|
||||
import MediaUI
|
||||
import Models
|
||||
import Status
|
||||
import Notifications
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
|
||||
|
@ -60,63 +61,109 @@ extension View {
|
|||
scrollToTopSignal: .constant(0),
|
||||
canFilterTimeline: false)
|
||||
case let .trendingLinks(cards):
|
||||
CardsListView(cards: cards)
|
||||
TrendingLinksListView(cards: cards)
|
||||
case let .tagsList(tags):
|
||||
TagsListView(tags: tags)
|
||||
case .notificationsRequests:
|
||||
NotificationsRequestsListView()
|
||||
case let .notificationForAccount(accountId):
|
||||
NotificationsListView(lockedType: nil,
|
||||
lockedAccountId: accountId,
|
||||
scrollToTopSignal: .constant(0))
|
||||
case .blockedAccounts:
|
||||
AccountsListView(mode: .blocked)
|
||||
case .mutedAccounts:
|
||||
AccountsListView(mode: .muted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func withSheetDestinations(sheetDestinations: Binding<SheetDestination?>) -> some View {
|
||||
sheet(item: sheetDestinations) { destination in
|
||||
Group {
|
||||
switch destination {
|
||||
case let .replyToStatusEditor(status):
|
||||
StatusEditorView(mode: .replyTo(status: status))
|
||||
case let .newStatusEditor(visibility):
|
||||
StatusEditorView(mode: .new(visibility: visibility))
|
||||
case let .editStatusEditor(status):
|
||||
StatusEditorView(mode: .edit(status: status))
|
||||
case let .quoteStatusEditor(status):
|
||||
StatusEditorView(mode: .quote(status: status))
|
||||
case let .mentionStatusEditor(account, visibility):
|
||||
StatusEditorView(mode: .mention(account: account, visibility: visibility))
|
||||
case .listCreate:
|
||||
ListCreateView()
|
||||
case let .listEdit(list):
|
||||
ListEditView(list: list)
|
||||
case let .listAddAccount(account):
|
||||
ListAddAccountView(account: account)
|
||||
case .addAccount:
|
||||
AddAccountView()
|
||||
case .addRemoteLocalTimeline:
|
||||
AddRemoteTimelineView()
|
||||
case .addTagGroup:
|
||||
EditTagGroupView()
|
||||
case let .statusEditHistory(status):
|
||||
StatusEditHistoryView(statusId: status)
|
||||
case .settings:
|
||||
SettingsTabs(popToRootTab: .constant(.settings), isModal: true)
|
||||
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
||||
case .accountPushNotficationsSettings:
|
||||
if let subscription = PushNotificationsService.shared.subscriptions.first(where: { $0.account.token == AppAccountsManager.shared.currentAccount.oauthToken }) {
|
||||
NavigationSheet { PushNotificationsView(subscription: subscription) }
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
case .about:
|
||||
NavigationSheet { AboutView() }
|
||||
case .support:
|
||||
NavigationSheet { SupportAppView() }
|
||||
case let .report(status):
|
||||
ReportView(status: status)
|
||||
case let .shareImage(image, status):
|
||||
ActivityView(image: image, status: status)
|
||||
case let .editTagGroup(tagGroup, onSaved):
|
||||
EditTagGroupView(tagGroup: tagGroup, onSaved: onSaved)
|
||||
switch destination {
|
||||
case let .replyToStatusEditor(status):
|
||||
StatusEditor.MainView(mode: .replyTo(status: status))
|
||||
.withEnvironments()
|
||||
case let .newStatusEditor(visibility):
|
||||
StatusEditor.MainView(mode: .new(text: nil, visibility: visibility))
|
||||
.withEnvironments()
|
||||
case let .prefilledStatusEditor(text, visibility):
|
||||
StatusEditor.MainView(mode: .new(text: text, visibility: visibility))
|
||||
.withEnvironments()
|
||||
case let .imageURL(urls, visibility):
|
||||
StatusEditor.MainView(mode: .imageURL(urls: urls, visibility: visibility))
|
||||
.withEnvironments()
|
||||
case let .editStatusEditor(status):
|
||||
StatusEditor.MainView(mode: .edit(status: status))
|
||||
.withEnvironments()
|
||||
case let .quoteStatusEditor(status):
|
||||
StatusEditor.MainView(mode: .quote(status: status))
|
||||
.withEnvironments()
|
||||
case let .quoteLinkStatusEditor(link):
|
||||
StatusEditor.MainView(mode: .quoteLink(link: link))
|
||||
.withEnvironments()
|
||||
case let .mentionStatusEditor(account, visibility):
|
||||
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
||||
.withEnvironments()
|
||||
case .listCreate:
|
||||
ListCreateView()
|
||||
.withEnvironments()
|
||||
case let .listEdit(list):
|
||||
ListEditView(list: list)
|
||||
.withEnvironments()
|
||||
case let .listAddAccount(account):
|
||||
ListAddAccountView(account: account)
|
||||
.withEnvironments()
|
||||
case .addAccount:
|
||||
AddAccountView()
|
||||
.withEnvironments()
|
||||
case .addRemoteLocalTimeline:
|
||||
AddRemoteTimelineView()
|
||||
.withEnvironments()
|
||||
case .addTagGroup:
|
||||
EditTagGroupView()
|
||||
.withEnvironments()
|
||||
case let .statusEditHistory(status):
|
||||
StatusEditHistoryView(statusId: status)
|
||||
.withEnvironments()
|
||||
case .settings:
|
||||
SettingsTabs(popToRootTab: .constant(.settings), isModal: true)
|
||||
.withEnvironments()
|
||||
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
||||
case .accountPushNotficationsSettings:
|
||||
if let subscription = PushNotificationsService.shared.subscriptions.first(where: { $0.account.token == AppAccountsManager.shared.currentAccount.oauthToken }) {
|
||||
NavigationSheet { PushNotificationsView(subscription: subscription) }
|
||||
.withEnvironments()
|
||||
} else {
|
||||
EmptyView()
|
||||
}
|
||||
case .about:
|
||||
NavigationSheet { AboutView() }
|
||||
.withEnvironments()
|
||||
case .support:
|
||||
NavigationSheet { SupportAppView() }
|
||||
.withEnvironments()
|
||||
case let .report(status):
|
||||
ReportView(status: status)
|
||||
.withEnvironments()
|
||||
case let .shareImage(image, status):
|
||||
ActivityView(image: image, status: status)
|
||||
.withEnvironments()
|
||||
case let .editTagGroup(tagGroup, onSaved):
|
||||
EditTagGroupView(tagGroup: tagGroup, onSaved: onSaved)
|
||||
.withEnvironments()
|
||||
case .timelineContentFilter:
|
||||
NavigationSheet { TimelineContentFilterView() }
|
||||
.presentationDetents([.medium])
|
||||
.presentationBackground(.thinMaterial)
|
||||
.withEnvironments()
|
||||
case .accountEditInfo:
|
||||
EditAccountView()
|
||||
.withEnvironments()
|
||||
case .accountFiltersList:
|
||||
FiltersListView()
|
||||
.withEnvironments()
|
||||
}
|
||||
.withEnvironments()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,6 +183,7 @@ extension View {
|
|||
Draft.self,
|
||||
LocalTimeline.self,
|
||||
TagGroup.self,
|
||||
RecentTag.self,
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<string>development</string>
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.$(BUNDLE_ID_PREFIX).IceCubesApp</string>
|
||||
<string>iCloud.icecubesapp</string>
|
||||
</array>
|
||||
<key>com.apple.developer.icloud-services</key>
|
||||
<array>
|
||||
|
|
|
@ -7,7 +7,7 @@ import KeychainSwift
|
|||
import MediaUI
|
||||
import Network
|
||||
import RevenueCat
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
|
||||
|
@ -17,36 +17,53 @@ struct AppView: View {
|
|||
@Environment(UserPreferences.self) private var userPreferences
|
||||
@Environment(Theme.self) private var theme
|
||||
@Environment(StreamWatcher.self) private var watcher
|
||||
|
||||
@Environment(\.horizontalSizeClass) var horizontalSizeClass
|
||||
|
||||
|
||||
@Environment(\.openWindow) var openWindow
|
||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||
|
||||
@Binding var selectedTab: Tab
|
||||
@Binding var sidebarRouterPath: RouterPath
|
||||
|
||||
@Binding var appRouterPath: RouterPath
|
||||
|
||||
@State var popToRootTab: Tab = .other
|
||||
@State var iosTabs = iOSTabs.shared
|
||||
@State var sideBarLoadedTabs: Set<Tab> = Set()
|
||||
|
||||
@State var sidebarTabs = SidebarTabs.shared
|
||||
|
||||
var body: some View {
|
||||
if (UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac) &&
|
||||
horizontalSizeClass == .regular {
|
||||
sidebarView
|
||||
} else {
|
||||
#if os(visionOS)
|
||||
tabBarView
|
||||
}
|
||||
#else
|
||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||
sidebarView
|
||||
} else {
|
||||
tabBarView
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
var availableTabs: [Tab] {
|
||||
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
||||
return appAccountsManager.currentClient.isAuth ? iosTabs.tabs : Tab.loggedOutTab()
|
||||
guard appAccountsManager.currentClient.isAuth else {
|
||||
return Tab.loggedOutTab()
|
||||
}
|
||||
return appAccountsManager.currentClient.isAuth ? Tab.loggedInTabs() : Tab.loggedOutTab()
|
||||
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
||||
return iosTabs.tabs
|
||||
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
||||
return Tab.visionOSTab()
|
||||
}
|
||||
return sidebarTabs.tabs.map { $0.tab }
|
||||
}
|
||||
|
||||
var tabBarView: some View {
|
||||
TabView(selection: .init(get: {
|
||||
selectedTab
|
||||
}, set: { newTab in
|
||||
if newTab == .post {
|
||||
#if os(visionOS)
|
||||
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
||||
#else
|
||||
appRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
||||
#endif
|
||||
return
|
||||
}
|
||||
if newTab == selectedTab {
|
||||
/// Stupid hack to trigger onChange binding in tab views.
|
||||
popToRootTab = .other
|
||||
|
@ -65,16 +82,18 @@ struct AppView: View {
|
|||
.tabItem {
|
||||
if userPreferences.showiPhoneTabLabel {
|
||||
tab.label
|
||||
.environment(\.symbolVariants, tab == selectedTab ? .fill : .none)
|
||||
} else {
|
||||
Image(systemName: tab.iconName)
|
||||
}
|
||||
}
|
||||
.tag(tab)
|
||||
.badge(badgeFor(tab: tab))
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .tabBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .tabBar)
|
||||
}
|
||||
}
|
||||
.id(appAccountsManager.currentClient.id)
|
||||
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
||||
}
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
|
@ -85,44 +104,41 @@ struct AppView: View {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var sidebarView: some View {
|
||||
SideBarView(selectedTab: $selectedTab,
|
||||
popToRootTab: $popToRootTab,
|
||||
tabs: availableTabs)
|
||||
{
|
||||
HStack(spacing: 0) {
|
||||
ZStack {
|
||||
if selectedTab == .profile {
|
||||
ProfileTab(popToRootTab: $popToRootTab)
|
||||
}
|
||||
ForEach(availableTabs) { tab in
|
||||
if tab == selectedTab || sideBarLoadedTabs.contains(tab) {
|
||||
|
||||
#if !os(visionOS)
|
||||
var sidebarView: some View {
|
||||
SideBarView(selectedTab: $selectedTab,
|
||||
popToRootTab: $popToRootTab,
|
||||
tabs: availableTabs)
|
||||
{
|
||||
HStack(spacing: 0) {
|
||||
TabView(selection: $selectedTab) {
|
||||
ForEach(availableTabs) { tab in
|
||||
tab
|
||||
.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
||||
.opacity(tab == selectedTab ? 1 : 0)
|
||||
.transition(.opacity)
|
||||
.id("\(tab)\(appAccountsManager.currentAccount.id)")
|
||||
.onAppear {
|
||||
sideBarLoadedTabs.insert(tab)
|
||||
.tabItem {
|
||||
tab.label
|
||||
}
|
||||
} else {
|
||||
EmptyView()
|
||||
.tag(tab)
|
||||
}
|
||||
}
|
||||
}
|
||||
if appAccountsManager.currentClient.isAuth,
|
||||
userPreferences.showiPadSecondaryColumn
|
||||
{
|
||||
Divider().edgesIgnoringSafeArea(.all)
|
||||
notificationsSecondaryColumn
|
||||
.introspect(.tabView, on: .iOS(.v17)) { (tabview: UITabBarController) in
|
||||
tabview.tabBar.isHidden = horizontalSizeClass == .regular
|
||||
tabview.customizableViewControllers = []
|
||||
tabview.moreNavigationController.isNavigationBarHidden = true
|
||||
}
|
||||
if horizontalSizeClass == .regular,
|
||||
appAccountsManager.currentClient.isAuth,
|
||||
userPreferences.showiPadSecondaryColumn
|
||||
{
|
||||
Divider().edgesIgnoringSafeArea(.all)
|
||||
notificationsSecondaryColumn
|
||||
}
|
||||
}
|
||||
}
|
||||
}.onChange(of: appAccountsManager.currentAccount.id) {
|
||||
sideBarLoadedTabs.removeAll()
|
||||
.environment(appRouterPath)
|
||||
}
|
||||
.environment(sidebarRouterPath)
|
||||
}
|
||||
#endif
|
||||
|
||||
var notificationsSecondaryColumn: some View {
|
||||
NotificationsTab(selectedTab: .constant(.notifications),
|
||||
|
@ -132,4 +148,3 @@ struct AppView: View {
|
|||
.id(appAccountsManager.currentAccount.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ extension IceCubesApp {
|
|||
#if targetEnvironment(macCatalyst)
|
||||
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
||||
#else
|
||||
sidebarRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
||||
appRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
||||
#endif
|
||||
}
|
||||
.keyboardShortcut("n", modifiers: .command)
|
||||
|
@ -54,5 +54,11 @@ extension IceCubesApp {
|
|||
}
|
||||
.keyboardShortcut("l", modifiers: .shift)
|
||||
}
|
||||
CommandGroup(replacing: .help) {
|
||||
Button("menu.help.github") {
|
||||
let url = URL(string: "https://github.com/Dimillian/IceCubesApp/issues")!
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import AppIntents
|
||||
import Env
|
||||
import MediaUI
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
|
||||
extension IceCubesApp {
|
||||
var appScene: some Scene {
|
||||
WindowGroup(id: "MainWindow") {
|
||||
AppView(selectedTab: $selectedTab, sidebarRouterPath: $sidebarRouterPath)
|
||||
AppView(selectedTab: $selectedTab, appRouterPath: $appRouterPath)
|
||||
.applyTheme(theme)
|
||||
.onAppear {
|
||||
setNewClientsInEnv(client: appAccountsManager.currentClient)
|
||||
|
@ -22,6 +23,7 @@ extension IceCubesApp {
|
|||
.environment(theme)
|
||||
.environment(watcher)
|
||||
.environment(pushNotificationsService)
|
||||
.environment(appIntentService)
|
||||
.environment(\.isSupporter, isSupporter)
|
||||
.sheet(item: $quickLook.selectedMediaAttachment) { selectedMediaAttachment in
|
||||
MediaUIView(selectedAttachment: selectedMediaAttachment,
|
||||
|
@ -47,8 +49,19 @@ extension IceCubesApp {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: appIntentService.handledIntent) { _, _ in
|
||||
if let intent = appIntentService.handledIntent?.intent {
|
||||
handleIntent(intent)
|
||||
appIntentService.handledIntent = nil
|
||||
}
|
||||
}
|
||||
.withModelContainer()
|
||||
}
|
||||
#if targetEnvironment(macCatalyst)
|
||||
.defaultSize(width: userPreferences.showiPadSecondaryColumn ? 1100 : 800, height: 1400)
|
||||
#elseif os(visionOS)
|
||||
.defaultSize(width: 800, height: 1200)
|
||||
#endif
|
||||
.commands {
|
||||
appMenu
|
||||
}
|
||||
|
@ -69,18 +82,25 @@ extension IceCubesApp {
|
|||
Group {
|
||||
switch destination.wrappedValue {
|
||||
case let .newStatusEditor(visibility):
|
||||
StatusEditorView(mode: .new(visibility: visibility))
|
||||
StatusEditor.MainView(mode: .new(text: nil, visibility: visibility))
|
||||
case let .prefilledStatusEditor(text, visibility):
|
||||
StatusEditor.MainView(mode: .new(text: text, visibility: visibility))
|
||||
case let .editStatusEditor(status):
|
||||
StatusEditorView(mode: .edit(status: status))
|
||||
StatusEditor.MainView(mode: .edit(status: status))
|
||||
case let .quoteStatusEditor(status):
|
||||
StatusEditorView(mode: .quote(status: status))
|
||||
StatusEditor.MainView(mode: .quote(status: status))
|
||||
case let .replyToStatusEditor(status):
|
||||
StatusEditorView(mode: .replyTo(status: status))
|
||||
StatusEditor.MainView(mode: .replyTo(status: status))
|
||||
case let .mentionStatusEditor(account, visibility):
|
||||
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
||||
case let .quoteLinkStatusEditor(link):
|
||||
StatusEditor.MainView(mode: .quoteLink(link: link))
|
||||
case .none:
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
.withEnvironments()
|
||||
.environment(RouterPath())
|
||||
.withModelContainer()
|
||||
.applyTheme(theme)
|
||||
.frame(minWidth: 300, minHeight: 400)
|
||||
|
@ -106,4 +126,23 @@ extension IceCubesApp {
|
|||
.defaultSize(width: 1200, height: 1000)
|
||||
.windowResizability(.contentMinSize)
|
||||
}
|
||||
|
||||
private func handleIntent(_: any AppIntent) {
|
||||
if let postIntent = appIntentService.handledIntent?.intent as? PostIntent {
|
||||
#if os(visionOS) || os(macOS)
|
||||
openWindow(value: WindowDestinationEditor.prefilledStatusEditor(text: postIntent.content ?? "",
|
||||
visibility: userPreferences.postVisibility))
|
||||
#else
|
||||
appRouterPath.presentedSheet = .prefilledStatusEditor(text: postIntent.content ?? "",
|
||||
visibility: userPreferences.postVisibility)
|
||||
#endif
|
||||
} else if let tabIntent = appIntentService.handledIntent?.intent as? TabIntent {
|
||||
selectedTab = tabIntent.tab.toAppTab
|
||||
} else if let imageIntent = appIntentService.handledIntent?.intent as? PostImageIntent,
|
||||
let urls = imageIntent.images?.compactMap({ $0.fileURL })
|
||||
{
|
||||
appRouterPath.presentedSheet = .imageURL(urls: urls,
|
||||
visibility: userPreferences.postVisibility)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import KeychainSwift
|
|||
import MediaUI
|
||||
import Network
|
||||
import RevenueCat
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
|
||||
|
@ -23,13 +23,14 @@ struct IceCubesApp: App {
|
|||
@State var currentAccount = CurrentAccount.shared
|
||||
@State var userPreferences = UserPreferences.shared
|
||||
@State var pushNotificationsService = PushNotificationsService.shared
|
||||
@State var appIntentService = AppIntentService.shared
|
||||
@State var watcher = StreamWatcher.shared
|
||||
@State var quickLook = QuickLook.shared
|
||||
@State var theme = Theme.shared
|
||||
|
||||
|
||||
@State var selectedTab: Tab = .timeline
|
||||
@State var sidebarRouterPath = RouterPath()
|
||||
|
||||
@State var appRouterPath = RouterPath()
|
||||
|
||||
@State var isSupporter: Bool = false
|
||||
|
||||
var body: some Scene {
|
||||
|
@ -79,11 +80,12 @@ struct IceCubesApp: App {
|
|||
}
|
||||
}
|
||||
|
||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
func application(_: UIApplication,
|
||||
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
||||
{
|
||||
try? AVAudioSession.sharedInstance().setCategory(.ambient)
|
||||
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
||||
try? AVAudioSession.sharedInstance().setActive(true)
|
||||
PushNotificationsService.shared.setAccounts(accounts: AppAccountsManager.shared.pushAccounts)
|
||||
return true
|
||||
}
|
||||
|
@ -112,4 +114,11 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
|||
}
|
||||
return configuration
|
||||
}
|
||||
|
||||
override func buildMenu(with builder: UIMenuBuilder) {
|
||||
super.buildMenu(with: builder)
|
||||
builder.remove(menu: .document)
|
||||
builder.remove(menu: .toolbar)
|
||||
builder.remove(menu: .sidebar)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import Network
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
|
||||
public struct ReportView: View {
|
||||
|
@ -36,43 +36,37 @@ public struct ReportView: View {
|
|||
.navigationTitle("report.title")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
#endif
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
isSendingReport = true
|
||||
Task {
|
||||
do {
|
||||
let _: ReportSent =
|
||||
try await client.post(endpoint: Statuses.report(accountId: status.account.id,
|
||||
statusId: status.id,
|
||||
comment: commentText))
|
||||
dismiss()
|
||||
isSendingReport = false
|
||||
} catch {
|
||||
isSendingReport = false
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button {
|
||||
isSendingReport = true
|
||||
Task {
|
||||
do {
|
||||
let _: ReportSent =
|
||||
try await client.post(endpoint: Statuses.report(accountId: status.account.id,
|
||||
statusId: status.id,
|
||||
comment: commentText))
|
||||
dismiss()
|
||||
isSendingReport = false
|
||||
} catch {
|
||||
isSendingReport = false
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
if isSendingReport {
|
||||
ProgressView()
|
||||
} else {
|
||||
Text("report.action.send")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
if isSendingReport {
|
||||
ProgressView()
|
||||
} else {
|
||||
Text("report.action.send")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Text("action.cancel")
|
||||
}
|
||||
CancelToolbarItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,25 +13,28 @@ extension View {
|
|||
|
||||
@MainActor
|
||||
private struct SafariRouter: ViewModifier {
|
||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||
@Environment(Theme.self) private var theme
|
||||
@Environment(UserPreferences.self) private var preferences
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
#if !os(visionOS)
|
||||
@State private var safariManager = InAppSafariManager()
|
||||
@State private var safariManager = InAppSafariManager()
|
||||
#endif
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
// Open internal URL.
|
||||
routerPath.handle(url: url)
|
||||
guard !isSecondaryColumn else { return .discarded }
|
||||
return routerPath.handle(url: url)
|
||||
})
|
||||
.onOpenURL { url in
|
||||
// Open external URL (from icecubesapp://)
|
||||
guard !isSecondaryColumn else { return }
|
||||
let urlString = url.absoluteString.replacingOccurrences(of: AppInfo.scheme, with: "https://")
|
||||
guard let url = URL(string: urlString), url.host != nil else { return }
|
||||
_ = routerPath.handle(url: url)
|
||||
_ = routerPath.handleDeepLink(url: url)
|
||||
}
|
||||
.onAppear {
|
||||
routerPath.urlHandler = { url in
|
||||
|
@ -47,81 +50,83 @@ private struct SafariRouter: ViewModifier {
|
|||
}
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
guard preferences.preferredBrowser == .inAppSafari else { return .systemAction }
|
||||
#endif
|
||||
// SFSafariViewController only supports initial URLs with http:// or https:// schemes.
|
||||
guard let scheme = url.scheme, ["https", "http"].contains(scheme.lowercased()) else {
|
||||
return .systemAction
|
||||
}
|
||||
#if os(visionOS)
|
||||
return .systemAction
|
||||
// SFSafariViewController only supports initial URLs with http:// or https:// schemes.
|
||||
guard let scheme = url.scheme, ["https", "http"].contains(scheme.lowercased()) else {
|
||||
return .systemAction
|
||||
}
|
||||
#if os(visionOS)
|
||||
return .systemAction
|
||||
#else
|
||||
return safariManager.open(url)
|
||||
#endif
|
||||
#else
|
||||
return safariManager.open(url)
|
||||
return .systemAction
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
#if !os(visionOS)
|
||||
.background {
|
||||
WindowReader { window in
|
||||
safariManager.windowScene = window.windowScene
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(visionOS)
|
||||
@MainActor
|
||||
@Observable private class InAppSafariManager: NSObject, SFSafariViewControllerDelegate {
|
||||
var windowScene: UIWindowScene?
|
||||
let viewController: UIViewController = .init()
|
||||
var window: UIWindow?
|
||||
|
||||
@MainActor
|
||||
func open(_ url: URL) -> OpenURLAction.Result {
|
||||
guard let windowScene else { return .systemAction }
|
||||
@Observable private class InAppSafariManager: NSObject, SFSafariViewControllerDelegate {
|
||||
var windowScene: UIWindowScene?
|
||||
let viewController: UIViewController = .init()
|
||||
var window: UIWindow?
|
||||
|
||||
window = setupWindow(windowScene: windowScene)
|
||||
@MainActor
|
||||
func open(_ url: URL) -> OpenURLAction.Result {
|
||||
guard let windowScene else { return .systemAction }
|
||||
|
||||
let configuration = SFSafariViewController.Configuration()
|
||||
configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView
|
||||
window = setupWindow(windowScene: windowScene)
|
||||
|
||||
let safari = SFSafariViewController(url: url, configuration: configuration)
|
||||
safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor)
|
||||
safari.preferredControlTintColor = UIColor(Theme.shared.tintColor)
|
||||
safari.delegate = self
|
||||
let configuration = SFSafariViewController.Configuration()
|
||||
configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.viewController.present(safari, animated: true)
|
||||
let safari = SFSafariViewController(url: url, configuration: configuration)
|
||||
safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor)
|
||||
safari.preferredControlTintColor = UIColor(Theme.shared.tintColor)
|
||||
safari.delegate = self
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.viewController.present(safari, animated: true)
|
||||
}
|
||||
|
||||
return .handled
|
||||
}
|
||||
|
||||
return .handled
|
||||
}
|
||||
func setupWindow(windowScene: UIWindowScene) -> UIWindow {
|
||||
let window = window ?? UIWindow(windowScene: windowScene)
|
||||
|
||||
func setupWindow(windowScene: UIWindowScene) -> UIWindow {
|
||||
let window = window ?? UIWindow(windowScene: windowScene)
|
||||
window.rootViewController = viewController
|
||||
window.makeKeyAndVisible()
|
||||
|
||||
window.rootViewController = viewController
|
||||
window.makeKeyAndVisible()
|
||||
switch Theme.shared.selectedScheme {
|
||||
case .dark:
|
||||
window.overrideUserInterfaceStyle = .dark
|
||||
case .light:
|
||||
window.overrideUserInterfaceStyle = .light
|
||||
}
|
||||
|
||||
switch Theme.shared.selectedScheme {
|
||||
case .dark:
|
||||
window.overrideUserInterfaceStyle = .dark
|
||||
case .light:
|
||||
window.overrideUserInterfaceStyle = .light
|
||||
self.window = window
|
||||
return window
|
||||
}
|
||||
|
||||
self.window = window
|
||||
return window
|
||||
}
|
||||
|
||||
nonisolated func safariViewControllerDidFinish(_: SFSafariViewController) {
|
||||
Task { @MainActor in
|
||||
window?.resignKey()
|
||||
window?.isHidden = false
|
||||
window = nil
|
||||
nonisolated func safariViewControllerDidFinish(_: SFSafariViewController) {
|
||||
Task { @MainActor in
|
||||
window?.resignKey()
|
||||
window?.isHidden = false
|
||||
window = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private struct WindowReader: UIViewRepresentable {
|
||||
|
|
|
@ -4,10 +4,12 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import SwiftUI
|
||||
import SwiftUIIntrospect
|
||||
|
||||
@MainActor
|
||||
struct SideBarView<Content: View>: View {
|
||||
@Environment(\.openWindow) private var openWindow
|
||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||
|
||||
@Environment(AppAccountsManager.self) private var appAccounts
|
||||
@Environment(CurrentAccount.self) private var currentAccount
|
||||
|
@ -21,6 +23,8 @@ struct SideBarView<Content: View>: View {
|
|||
var tabs: [Tab]
|
||||
@ViewBuilder var content: () -> Content
|
||||
|
||||
@State private var sidebarTabs = SidebarTabs.shared
|
||||
|
||||
private func badgeFor(tab: Tab) -> Int {
|
||||
if tab == .notifications, selectedTab != tab,
|
||||
let token = appAccounts.currentAccount.oauthToken
|
||||
|
@ -31,16 +35,25 @@ struct SideBarView<Content: View>: View {
|
|||
}
|
||||
|
||||
private func makeIconForTab(tab: Tab) -> some View {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
SideBarIcon(systemIconName: tab.iconName,
|
||||
isSelected: tab == selectedTab)
|
||||
let badge = badgeFor(tab: tab)
|
||||
if badge > 0 {
|
||||
makeBadgeView(count: badge)
|
||||
HStack {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
SideBarIcon(systemIconName: tab.iconName,
|
||||
isSelected: tab == selectedTab)
|
||||
let badge = badgeFor(tab: tab)
|
||||
if badge > 0 {
|
||||
makeBadgeView(count: badge)
|
||||
}
|
||||
}
|
||||
if userPreferences.isSidebarExpanded {
|
||||
Text(tab.title)
|
||||
.font(.headline)
|
||||
.foregroundColor(tab == selectedTab ? theme.tintColor : theme.labelColor)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.frame(width: .sidebarWidth, height: 50)
|
||||
.frame(width: (userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth) - 24, height: 50)
|
||||
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear,
|
||||
in: RoundedRectangle(cornerRadius: 8))
|
||||
}
|
||||
|
||||
private func makeBadgeView(count: Int) -> some View {
|
||||
|
@ -57,7 +70,7 @@ struct SideBarView<Content: View>: View {
|
|||
|
||||
private var postButton: some View {
|
||||
Button {
|
||||
#if targetEnvironment(macCatalyst)
|
||||
#if targetEnvironment(macCatalyst) || os(visionOS)
|
||||
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
||||
#else
|
||||
routerPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
||||
|
@ -67,8 +80,10 @@ struct SideBarView<Content: View>: View {
|
|||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 20, height: 30)
|
||||
.offset(x: 2, y: -2)
|
||||
}
|
||||
.buttonStyle(.borderedProminent)
|
||||
.help(Tab.post.title)
|
||||
}
|
||||
|
||||
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
||||
|
@ -85,8 +100,19 @@ struct SideBarView<Content: View>: View {
|
|||
}
|
||||
} label: {
|
||||
ZStack(alignment: .topTrailing) {
|
||||
AppAccountView(viewModel: .init(appAccount: account, isCompact: true))
|
||||
if showBadge,
|
||||
if userPreferences.isSidebarExpanded {
|
||||
AppAccountView(viewModel: .init(appAccount: account,
|
||||
isCompact: false,
|
||||
isInSettings: false),
|
||||
isParentPresented: .constant(false))
|
||||
} else {
|
||||
AppAccountView(viewModel: .init(appAccount: account,
|
||||
isCompact: true,
|
||||
isInSettings: false),
|
||||
isParentPresented: .constant(false))
|
||||
}
|
||||
if !userPreferences.isSidebarExpanded,
|
||||
showBadge,
|
||||
let token = account.oauthToken,
|
||||
let notificationsCount = userPreferences.notificationsCount[token],
|
||||
notificationsCount > 0
|
||||
|
@ -94,69 +120,95 @@ struct SideBarView<Content: View>: View {
|
|||
makeBadgeView(count: notificationsCount)
|
||||
}
|
||||
}
|
||||
.padding(.leading, userPreferences.isSidebarExpanded ? 16 : 0)
|
||||
}
|
||||
.frame(width: .sidebarWidth, height: 50)
|
||||
.help(accountButtonTitle(accountName: account.accountName))
|
||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth, height: 50)
|
||||
.padding(.vertical, 8)
|
||||
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
||||
theme.secondaryBackgroundColor : .clear)
|
||||
}
|
||||
|
||||
private func accountButtonTitle(accountName: String?) -> LocalizedStringKey {
|
||||
if let accountName {
|
||||
"tab.profile-account-\(accountName)"
|
||||
} else {
|
||||
Tab.profile.title
|
||||
}
|
||||
}
|
||||
|
||||
private var tabsView: some View {
|
||||
ForEach(tabs) { tab in
|
||||
Button {
|
||||
// ensure keyboard is always dismissed when selecting a tab
|
||||
hideKeyboard()
|
||||
if tab != .profile && sidebarTabs.isEnabled(tab) {
|
||||
Button {
|
||||
// ensure keyboard is always dismissed when selecting a tab
|
||||
hideKeyboard()
|
||||
|
||||
if tab == selectedTab {
|
||||
popToRootTab = .other
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
||||
popToRootTab = tab
|
||||
if tab == selectedTab {
|
||||
popToRootTab = .other
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
||||
popToRootTab = tab
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedTab = tab
|
||||
SoundEffectManager.shared.playSound(.tabSelection)
|
||||
if tab == .notifications {
|
||||
if let token = appAccounts.currentAccount.oauthToken {
|
||||
userPreferences.notificationsCount[token] = 0
|
||||
selectedTab = tab
|
||||
SoundEffectManager.shared.playSound(.tabSelection)
|
||||
if tab == .notifications {
|
||||
if let token = appAccounts.currentAccount.oauthToken {
|
||||
userPreferences.notificationsCount[token] = 0
|
||||
}
|
||||
watcher.unreadNotificationsCount = 0
|
||||
}
|
||||
watcher.unreadNotificationsCount = 0
|
||||
} label: {
|
||||
makeIconForTab(tab: tab)
|
||||
}
|
||||
} label: {
|
||||
makeIconForTab(tab: tab)
|
||||
.help(tab.title)
|
||||
}
|
||||
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@Bindable var routerPath = routerPath
|
||||
HStack(spacing: 0) {
|
||||
ScrollView {
|
||||
VStack(alignment: .center) {
|
||||
if appAccounts.availableAccounts.isEmpty {
|
||||
tabsView
|
||||
} else {
|
||||
ForEach(appAccounts.availableAccounts) { account in
|
||||
makeAccountButton(account: account,
|
||||
showBadge: account.id != appAccounts.currentAccount.id)
|
||||
if account.id == appAccounts.currentAccount.id {
|
||||
tabsView
|
||||
if horizontalSizeClass == .regular {
|
||||
ScrollView {
|
||||
VStack(alignment: .center) {
|
||||
if appAccounts.availableAccounts.isEmpty {
|
||||
tabsView
|
||||
} else {
|
||||
ForEach(appAccounts.availableAccounts) { account in
|
||||
makeAccountButton(account: account,
|
||||
showBadge: account.id != appAccounts.currentAccount.id)
|
||||
if account.id == appAccounts.currentAccount.id {
|
||||
tabsView
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
postButton
|
||||
.padding(.top, 12)
|
||||
Spacer()
|
||||
}
|
||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(.thinMaterial)
|
||||
.safeAreaInset(edge: .bottom, content: {
|
||||
HStack(spacing: 16) {
|
||||
postButton
|
||||
.padding(.vertical, 24)
|
||||
.padding(.leading, userPreferences.isSidebarExpanded ? 18 : 0)
|
||||
if userPreferences.isSidebarExpanded {
|
||||
Text("menu.new-post")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(theme.labelColor)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth)
|
||||
.background(.thinMaterial)
|
||||
})
|
||||
Divider().edgesIgnoringSafeArea(.all)
|
||||
}
|
||||
.frame(width: .sidebarWidth)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(.thinMaterial)
|
||||
Divider()
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
content()
|
||||
}
|
||||
.background(.thinMaterial)
|
||||
.edgesIgnoringSafeArea(.bottom)
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
}
|
||||
}
|
||||
|
@ -174,12 +226,14 @@ private struct SideBarIcon: View {
|
|||
.font(.title2)
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(isSelected ? theme.tintColor : theme.labelColor)
|
||||
.symbolVariant(isSelected ? .fill : .none)
|
||||
.scaleEffect(isHovered ? 0.8 : 1.0)
|
||||
.onHover { isHovered in
|
||||
withAnimation(.interpolatingSpring(stiffness: 300, damping: 15)) {
|
||||
self.isHovered = isHovered
|
||||
}
|
||||
}
|
||||
.frame(width: 50, height: 40)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import Env
|
|||
import Explore
|
||||
import Models
|
||||
import Network
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -22,7 +21,7 @@ struct ExploreTab: View {
|
|||
ExploreView(scrollToTopSignal: $scrollToTopSignal)
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.toolbar {
|
||||
ToolbarTab(routerPath: $routerPath)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import Network
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -27,7 +26,7 @@ struct MessagesTab: View {
|
|||
.toolbar {
|
||||
ToolbarTab(routerPath: $routerPath)
|
||||
}
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.id(client.id)
|
||||
}
|
||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
||||
|
|
|
@ -1,29 +1,23 @@
|
|||
import SwiftUI
|
||||
import Env
|
||||
import AppAccount
|
||||
import DesignSystem
|
||||
import Env
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
struct NavigationSheet<Content: View>: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
|
||||
|
||||
var content: () -> Content
|
||||
|
||||
|
||||
init(@ViewBuilder content: @escaping () -> Content) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
content()
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle")
|
||||
}
|
||||
}
|
||||
CloseToolbarItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,45 @@
|
|||
import SwiftUI
|
||||
import Env
|
||||
import AppAccount
|
||||
import DesignSystem
|
||||
import Env
|
||||
import Network
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
struct NavigationTab<Content: View>: View {
|
||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||
|
||||
|
||||
@Environment(AppAccountsManager.self) private var appAccount
|
||||
@Environment(CurrentAccount.self) private var currentAccount
|
||||
@Environment(UserPreferences.self) private var userPreferences
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
@Environment(Client.self) private var client
|
||||
|
||||
var content: () -> Content
|
||||
|
||||
|
||||
@State private var routerPath = RouterPath()
|
||||
|
||||
|
||||
init(@ViewBuilder content: @escaping () -> Content) {
|
||||
self.content = content
|
||||
}
|
||||
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
content()
|
||||
.withEnvironments()
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.withSafariRouter()
|
||||
.toolbar {
|
||||
ToolbarTab(routerPath: $routerPath)
|
||||
}
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.onChange(of: client.id) {
|
||||
routerPath.path = []
|
||||
}
|
||||
.onAppear {
|
||||
routerPath.client = client
|
||||
}
|
||||
.withSafariRouter()
|
||||
}
|
||||
.environment(routerPath)
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ struct NotificationsTab: View {
|
|||
@Environment(PushNotificationsService.self) private var pushNotificationsService
|
||||
@State private var routerPath = RouterPath()
|
||||
@State private var scrollToTopSignal: Int = 0
|
||||
|
||||
|
||||
@Binding var selectedTab: Tab
|
||||
@Binding var popToRootTab: Tab
|
||||
|
||||
|
@ -37,12 +37,12 @@ struct NotificationsTab: View {
|
|||
Button {
|
||||
routerPath.presentedSheet = .accountPushNotficationsSettings
|
||||
} label: {
|
||||
Image(systemName: "bell.badge")
|
||||
Image(systemName: "bell")
|
||||
}
|
||||
}
|
||||
ToolbarTab(routerPath: $routerPath)
|
||||
}
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.id(client.id)
|
||||
}
|
||||
.onAppear {
|
||||
|
@ -60,9 +60,9 @@ struct NotificationsTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedTab, { _, newValue in
|
||||
.onChange(of: selectedTab) { _, _ in
|
||||
clearNotifications()
|
||||
})
|
||||
}
|
||||
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
|
||||
if let newValue, let type = newValue.notification.supportedType {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import DesignSystem
|
|||
import Env
|
||||
import Models
|
||||
import Network
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -24,7 +23,7 @@ struct ProfileTab: View {
|
|||
AccountDetailView(account: account, scrollToTopSignal: $scrollToTopSignal)
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.id(account.id)
|
||||
} else {
|
||||
AccountDetailView(account: .placeholder(), scrollToTopSignal: $scrollToTopSignal)
|
||||
|
|
|
@ -27,27 +27,27 @@ struct AboutView: View {
|
|||
var body: some View {
|
||||
List {
|
||||
Section {
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
HStack {
|
||||
Spacer()
|
||||
Image(uiImage: .init(named: "AppIconAlternate0")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate4")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate17")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate23")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Spacer()
|
||||
}
|
||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
||||
HStack {
|
||||
Spacer()
|
||||
Image(uiImage: .init(named: "AppIconAlternate0")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate4")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate17")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Image(uiImage: .init(named: "AppIconAlternate23")!)
|
||||
.resizable()
|
||||
.frame(width: 50, height: 50)
|
||||
.cornerRadius(4)
|
||||
Spacer()
|
||||
}
|
||||
#endif
|
||||
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp/blob/main/PRIVACY.MD")!) {
|
||||
Label("settings.support.privacy-policy", systemImage: "lock")
|
||||
|
@ -57,7 +57,7 @@ struct AboutView: View {
|
|||
Label("settings.support.terms-of-use", systemImage: "checkmark.shield")
|
||||
}
|
||||
} footer: {
|
||||
Text("\(versionNumber)©2023 Thomas Ricouard")
|
||||
Text("\(versionNumber)© 2024 Thomas Ricouard")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
|
@ -107,14 +107,14 @@ struct AboutView: View {
|
|||
}
|
||||
.listStyle(.insetGrouped)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.navigationTitle(Text("settings.about.title"))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
routerPath.handle(url: url)
|
||||
})
|
||||
.navigationTitle(Text("settings.about.title"))
|
||||
.navigationBarTitleDisplayMode(.large)
|
||||
.environment(\.openURL, OpenURLAction { url in
|
||||
routerPath.handle(url: url)
|
||||
})
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
|
|
@ -17,9 +17,8 @@ struct AccountSettingsView: View {
|
|||
@Environment(Theme.self) private var theme
|
||||
@Environment(AppAccountsManager.self) private var appAccountsManager
|
||||
@Environment(Client.self) private var client
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
|
||||
@State private var isEditingAccount: Bool = false
|
||||
@State private var isEditingFilters: Bool = false
|
||||
@State private var cachedPostsCount: Int = 0
|
||||
@State private var timelineCache = TimelineCache()
|
||||
|
||||
|
@ -30,7 +29,7 @@ struct AccountSettingsView: View {
|
|||
Form {
|
||||
Section {
|
||||
Button {
|
||||
isEditingAccount = true
|
||||
routerPath.presentedSheet = .accountEditInfo
|
||||
} label: {
|
||||
Label("account.action.edit-info", systemImage: "pencil")
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
@ -40,7 +39,7 @@ struct AccountSettingsView: View {
|
|||
|
||||
if currentInstance.isFiltersSupported {
|
||||
Button {
|
||||
isEditingFilters = true
|
||||
routerPath.presentedSheet = .accountFiltersList
|
||||
} label: {
|
||||
Label("account.action.edit-filters", systemImage: "line.3.horizontal.decrease.circle")
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
@ -96,12 +95,6 @@ struct AccountSettingsView: View {
|
|||
}
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
}
|
||||
.sheet(isPresented: $isEditingAccount, content: {
|
||||
EditAccountView()
|
||||
})
|
||||
.sheet(isPresented: $isEditingFilters, content: {
|
||||
FiltersListView()
|
||||
})
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .principal) {
|
||||
HStack {
|
||||
|
@ -116,8 +109,8 @@ struct AccountSettingsView: View {
|
|||
}
|
||||
.navigationTitle(account.safeDisplayName)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import Models
|
|||
import Network
|
||||
import NukeUI
|
||||
import SafariServices
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -83,77 +82,75 @@ struct AddAccountView: View {
|
|||
.navigationTitle("account.add.navigation-title")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
#endif
|
||||
.toolbar {
|
||||
if !appAccountsManager.availableAccounts.isEmpty {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button("action.cancel", action: { dismiss() })
|
||||
.toolbar {
|
||||
if !appAccountsManager.availableAccounts.isEmpty {
|
||||
CancelToolbarItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
isInstanceURLFieldFocused = true
|
||||
Task {
|
||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||
withAnimation {
|
||||
self.instances = instances
|
||||
}
|
||||
}
|
||||
isSigninIn = false
|
||||
}
|
||||
.onChange(of: instanceName) {
|
||||
searchingTask.cancel()
|
||||
searchingTask = Task {
|
||||
try? await Task.sleep(for: .seconds(0.1))
|
||||
guard !Task.isCancelled else { return }
|
||||
|
||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||
withAnimation {
|
||||
self.instances = instances
|
||||
}
|
||||
}
|
||||
|
||||
getInstanceDetailTask.cancel()
|
||||
getInstanceDetailTask = Task {
|
||||
try? await Task.sleep(for: .seconds(0.1))
|
||||
guard !Task.isCancelled else { return }
|
||||
|
||||
do {
|
||||
// bare bones preflight for domain validity
|
||||
let instanceDetailClient = Client(server: sanitizedName)
|
||||
if
|
||||
instanceDetailClient.server.contains("."),
|
||||
instanceDetailClient.server.last != "."
|
||||
{
|
||||
let instance: Instance = try await instanceDetailClient.get(endpoint: Instances.instance)
|
||||
withAnimation {
|
||||
self.instance = instance
|
||||
instanceName = sanitizedName // clean up the text box, principally to chop off the username if present so it's clear that you might not wind up siging in as the thing in the box
|
||||
}
|
||||
instanceFetchError = nil
|
||||
} else {
|
||||
instance = nil
|
||||
instanceFetchError = nil
|
||||
.onAppear {
|
||||
isInstanceURLFieldFocused = true
|
||||
Task {
|
||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||
withAnimation {
|
||||
self.instances = instances
|
||||
}
|
||||
}
|
||||
isSigninIn = false
|
||||
}
|
||||
.onChange(of: instanceName) {
|
||||
searchingTask.cancel()
|
||||
searchingTask = Task {
|
||||
try? await Task.sleep(for: .seconds(0.1))
|
||||
guard !Task.isCancelled else { return }
|
||||
|
||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||
withAnimation {
|
||||
self.instances = instances
|
||||
}
|
||||
}
|
||||
|
||||
getInstanceDetailTask.cancel()
|
||||
getInstanceDetailTask = Task {
|
||||
try? await Task.sleep(for: .seconds(0.1))
|
||||
guard !Task.isCancelled else { return }
|
||||
|
||||
do {
|
||||
// bare bones preflight for domain validity
|
||||
let instanceDetailClient = Client(server: sanitizedName)
|
||||
if
|
||||
instanceDetailClient.server.contains("."),
|
||||
instanceDetailClient.server.last != "."
|
||||
{
|
||||
let instance: Instance = try await instanceDetailClient.get(endpoint: Instances.instance)
|
||||
withAnimation {
|
||||
self.instance = instance
|
||||
instanceName = sanitizedName // clean up the text box, principally to chop off the username if present so it's clear that you might not wind up siging in as the thing in the box
|
||||
}
|
||||
instanceFetchError = nil
|
||||
} else {
|
||||
instance = nil
|
||||
instanceFetchError = nil
|
||||
}
|
||||
} catch _ as DecodingError {
|
||||
instance = nil
|
||||
instanceFetchError = "account.add.error.instance-not-supported"
|
||||
} catch {
|
||||
instance = nil
|
||||
}
|
||||
} catch _ as DecodingError {
|
||||
instance = nil
|
||||
instanceFetchError = "account.add.error.instance-not-supported"
|
||||
} catch {
|
||||
instance = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
.onChange(of: scenePhase) { _, newValue in
|
||||
switch newValue {
|
||||
case .active:
|
||||
isSigninIn = false
|
||||
default:
|
||||
break
|
||||
.onChange(of: scenePhase) { _, newValue in
|
||||
switch newValue {
|
||||
case .active:
|
||||
isSigninIn = false
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,9 +214,9 @@ struct AddAccountView: View {
|
|||
.foregroundColor(.primary)
|
||||
Spacer()
|
||||
(Text("instance.list.users-\(formatAsNumber(instance.users))")
|
||||
+ Text(" ⸱ ")
|
||||
+ Text("instance.list.posts-\(formatAsNumber(instance.statuses))"))
|
||||
.foregroundStyle(theme.tintColor)
|
||||
+ Text(" ⸱ ")
|
||||
+ Text("instance.list.posts-\(formatAsNumber(instance.statuses))"))
|
||||
.foregroundStyle(theme.tintColor)
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
Text(instance.info?.shortDescription?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "")
|
||||
|
@ -265,9 +262,8 @@ struct AddAccountView: View {
|
|||
}
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
.shimmering()
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -306,13 +302,3 @@ struct AddAccountView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SafariView: UIViewControllerRepresentable {
|
||||
let url: URL
|
||||
|
||||
func makeUIViewController(context _: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
|
||||
SFSafariViewController(url: url)
|
||||
}
|
||||
|
||||
func updateUIViewController(_: SFSafariViewController, context _: UIViewControllerRepresentableContext<SafariView>) {}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import Models
|
|||
import Network
|
||||
import NukeUI
|
||||
import SwiftUI
|
||||
import Timeline
|
||||
import UserNotifications
|
||||
|
||||
@MainActor
|
||||
|
@ -12,22 +13,18 @@ struct ContentSettingsView: View {
|
|||
@Environment(UserPreferences.self) private var userPreferences
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
@State private var contentFilter = TimelineContentFilter.shared
|
||||
|
||||
var body: some View {
|
||||
@Bindable var userPreferences = userPreferences
|
||||
Form {
|
||||
Section("settings.content.boosts") {
|
||||
Toggle(isOn: $userPreferences.suppressDupeReblogs) {
|
||||
Text("settings.content.hide-repeated-boosts")
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
Section("settings.content.media") {
|
||||
Toggle(isOn: $userPreferences.autoPlayVideo) {
|
||||
Text("settings.other.autoplay-video")
|
||||
}
|
||||
Toggle(isOn: $userPreferences.muteVideo) {
|
||||
Text("settings.other.mute-video")
|
||||
}
|
||||
Toggle(isOn: $userPreferences.showAltTextForMedia) {
|
||||
Text("settings.content.media.show.alt")
|
||||
}
|
||||
|
@ -44,7 +41,7 @@ struct ContentSettingsView: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
|
@ -62,6 +59,7 @@ struct ContentSettingsView: View {
|
|||
userPreferences.appAutoExpandMedia = userPreferences.autoExpandMedia
|
||||
userPreferences.appDefaultPostsSensitive = userPreferences.postIsSensitive
|
||||
userPreferences.appDefaultPostVisibility = userPreferences.postVisibility
|
||||
userPreferences.appRequireAltText = userPreferences.appRequireAltText
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +84,7 @@ struct ContentSettingsView: View {
|
|||
} footer: {
|
||||
Text("settings.content.collapse-long-posts-hint")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
|
@ -115,6 +113,28 @@ struct ContentSettingsView: View {
|
|||
Text("settings.content.default-sensitive")
|
||||
}
|
||||
.disabled(userPreferences.useInstanceContentSettings)
|
||||
|
||||
Toggle(isOn: $userPreferences.appRequireAltText) {
|
||||
Text("settings.content.require-alt-text")
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
Section("timeline.content-filter.title") {
|
||||
Toggle(isOn: $contentFilter.showBoosts) {
|
||||
Label("timeline.filter.show-boosts", image: "Rocket")
|
||||
}
|
||||
Toggle(isOn: $contentFilter.showReplies) {
|
||||
Label("timeline.filter.show-replies", systemImage: "bubble.left.and.bubble.right")
|
||||
}
|
||||
Toggle(isOn: $contentFilter.showThreads) {
|
||||
Label("timeline.filter.show-threads", systemImage: "bubble.left.and.text.bubble.right")
|
||||
}
|
||||
Toggle(isOn: $contentFilter.showQuotePosts) {
|
||||
Label("timeline.filter.show-quote", systemImage: "quote.bubble")
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
|
@ -122,8 +142,8 @@ struct ContentSettingsView: View {
|
|||
}
|
||||
.navigationTitle("settings.content.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,10 @@ import Env
|
|||
import Models
|
||||
import Network
|
||||
import Observation
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
@Observable class DisplaySettingsLocalValues {
|
||||
var tintColor = Theme.shared.tintColor
|
||||
var primaryBackgroundColor = Theme.shared.primaryBackgroundColor
|
||||
|
@ -35,11 +36,13 @@ struct DisplaySettingsView: View {
|
|||
var body: some View {
|
||||
ZStack(alignment: .top) {
|
||||
Form {
|
||||
StatusRowView(viewModel: previewStatusViewModel)
|
||||
.allowsHitTesting(false)
|
||||
.opacity(0)
|
||||
.hidden()
|
||||
themeSection
|
||||
#if !os(visionOS)
|
||||
StatusRowView(viewModel: previewStatusViewModel)
|
||||
.allowsHitTesting(false)
|
||||
.opacity(0)
|
||||
.hidden()
|
||||
themeSection
|
||||
#endif
|
||||
fontSection
|
||||
layoutSection
|
||||
platformsSection
|
||||
|
@ -47,34 +50,36 @@ struct DisplaySettingsView: View {
|
|||
}
|
||||
.navigationTitle("settings.display.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.task(id: localValues.tintColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.tintColor = localValues.tintColor
|
||||
}
|
||||
.task(id: localValues.primaryBackgroundColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.primaryBackgroundColor = localValues.primaryBackgroundColor
|
||||
}
|
||||
.task(id: localValues.secondaryBackgroundColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.secondaryBackgroundColor = localValues.secondaryBackgroundColor
|
||||
}
|
||||
.task(id: localValues.labelColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.labelColor = localValues.labelColor
|
||||
}
|
||||
.task(id: localValues.lineSpacing) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.lineSpacing = localValues.lineSpacing
|
||||
}
|
||||
.task(id: localValues.fontSizeScale) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.fontSizeScale = localValues.fontSizeScale
|
||||
}
|
||||
#if !os(visionOS)
|
||||
examplePost
|
||||
#endif
|
||||
.task(id: localValues.tintColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.tintColor = localValues.tintColor
|
||||
}
|
||||
.task(id: localValues.primaryBackgroundColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.primaryBackgroundColor = localValues.primaryBackgroundColor
|
||||
}
|
||||
.task(id: localValues.secondaryBackgroundColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.secondaryBackgroundColor = localValues.secondaryBackgroundColor
|
||||
}
|
||||
.task(id: localValues.labelColor) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.labelColor = localValues.labelColor
|
||||
}
|
||||
.task(id: localValues.lineSpacing) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.lineSpacing = localValues.lineSpacing
|
||||
}
|
||||
.task(id: localValues.fontSizeScale) {
|
||||
do { try await Task.sleep(for: .microseconds(500)) } catch {}
|
||||
theme.fontSizeScale = localValues.fontSizeScale
|
||||
}
|
||||
examplePost
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +248,7 @@ struct DisplaySettingsView: View {
|
|||
@Bindable var userPreferences = userPreferences
|
||||
|
||||
if UIDevice.current.userInterfaceIdiom == .pad {
|
||||
Section("iPad") {
|
||||
Section("settings.display.section.platform") {
|
||||
Toggle("settings.display.show-ipad-column", isOn: $userPreferences.showiPadSecondaryColumn)
|
||||
}
|
||||
#if !os(visionOS)
|
||||
|
@ -255,21 +260,7 @@ struct DisplaySettingsView: View {
|
|||
private var resetSection: some View {
|
||||
Section {
|
||||
Button {
|
||||
theme.followSystemColorScheme = true
|
||||
theme.applySet(set: colorScheme == .dark ? .iceCubeDark : .iceCubeLight)
|
||||
theme.avatarShape = .circle
|
||||
theme.avatarPosition = .leading
|
||||
theme.statusActionsDisplay = .full
|
||||
theme.displayFullUsername = false
|
||||
theme.statusDisplayStyle = .large
|
||||
theme.lineSpacing = 1.2
|
||||
theme.fontSizeScale = 1.0
|
||||
|
||||
localValues.tintColor = theme.tintColor
|
||||
localValues.primaryBackgroundColor = theme.primaryBackgroundColor
|
||||
localValues.secondaryBackgroundColor = theme.secondaryBackgroundColor
|
||||
localValues.labelColor = theme.labelColor
|
||||
|
||||
theme.restoreDefault()
|
||||
} label: {
|
||||
Text("settings.display.restore")
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import Models
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -23,8 +23,8 @@ struct HapticSettingsView: View {
|
|||
}
|
||||
.navigationTitle("settings.haptic.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,19 +17,16 @@ struct IconSelectorView: View {
|
|||
}
|
||||
|
||||
case primary = 0
|
||||
case alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8
|
||||
case alt9, alt10, alt11, alt12, alt13, alt14
|
||||
case alt15, alt16, alt17, alt18, alt19, alt20, alt21
|
||||
case alt22, alt23, alt24, alt25
|
||||
case alt26, alt27, alt28
|
||||
case alt29, alt30, alt31, alt32
|
||||
case alt33
|
||||
case alt34, alt35
|
||||
case alt36
|
||||
case alt1, alt2, alt3, alt4, alt5, alt6, alt7, alt8, alt9, alt10, alt11, alt12, alt13, alt14, alt15
|
||||
case alt16, alt17, alt18, alt19, alt20, alt21
|
||||
case alt22, alt23, alt24, alt25, alt26
|
||||
case alt27, alt28, alt29
|
||||
case alt30, alt31, alt32, alt33, alt34, alt35, alt36
|
||||
case alt37
|
||||
case alt38, alt39
|
||||
case alt40, alt41, alt42
|
||||
case alt43, alt44, alt45, alt46, alt47, alt48, alt49, alt50, alt51
|
||||
case alt38
|
||||
case alt39, alt40, alt41, alt42, alt43
|
||||
case alt44, alt45
|
||||
case alt46
|
||||
|
||||
var appIconName: String {
|
||||
return "AppIconAlternate\(rawValue)"
|
||||
|
@ -42,17 +39,18 @@ struct IconSelectorView: View {
|
|||
let icons: [Icon]
|
||||
|
||||
static let items = [
|
||||
IconSelector(title: "settings.app.icon.official".localized, icons: [.primary, .alt50, .alt1, .alt2, .alt3, .alt4, .alt5, .alt6, .alt7, .alt8,
|
||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14,
|
||||
.alt15, .alt16, .alt17, .alt18, .alt19, .alt25,
|
||||
.alt43, .alt44, .alt45, .alt46, .alt47, .alt51]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Albert Kinng", icons: [.alt20, .alt21, .alt22, .alt23, .alt24]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Dan van Moll", icons: [.alt26, .alt27, .alt28]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Chanhwi Joo (GitHub @te6-in)", icons: [.alt29, .alt34, .alt31, .alt35, .alt30, .alt32, .alt40]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) W. Kovács Ágnes (@wildgica)", icons: [.alt33]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Duncan Horne", icons: [.alt36]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) BeAware@social.beaware.live", icons: [.alt37, .alt41, .alt42, .alt48, .alt49]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Simone Margio", icons: [.alt38, .alt39]),
|
||||
IconSelector(title: "settings.app.icon.official".localized, icons: [
|
||||
.primary, .alt46, .alt1, .alt2, .alt3, .alt4,
|
||||
.alt5, .alt6, .alt7, .alt8,
|
||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14, .alt15,
|
||||
.alt16, .alt17, .alt18, .alt19, .alt20, .alt21]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Albert Kinng", icons: [.alt22, .alt23, .alt24, .alt25, .alt26]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Dan van Moll", icons: [.alt27, .alt28, .alt29]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Chanhwi Joo (GitHub @te6-in)", icons: [.alt30, .alt31, .alt32, .alt33, .alt34, .alt35, .alt36]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) W. Kovács Ágnes (@wildgica)", icons: [.alt37]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Duncan Horne", icons: [.alt38]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) BeAware@social.beaware.live", icons: [.alt39, .alt40, .alt41, .alt42, .alt43]),
|
||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Simone Margio", icons: [.alt44, .alt45]),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ struct InstanceInfoView: View {
|
|||
}
|
||||
.navigationTitle("instance.info.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,12 +111,12 @@ struct PushNotificationsView: View {
|
|||
}
|
||||
.navigationTitle("settings.push.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.task {
|
||||
await subscription.fetchSubscription()
|
||||
}
|
||||
.task {
|
||||
await subscription.fetchSubscription()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateSubscription() {
|
||||
|
|
44
IceCubesApp/App/Tabs/Settings/RecenTagsSettingView.swift
Normal file
|
@ -0,0 +1,44 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import Models
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
struct RecenTagsSettingView: View {
|
||||
@Environment(\.modelContext) private var context
|
||||
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
@Query(sort: \RecentTag.lastUse, order: .reverse) var tags: [RecentTag]
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
ForEach(tags) { tag in
|
||||
VStack(alignment: .leading) {
|
||||
Text("#\(tag.title)")
|
||||
.font(.scaledBody)
|
||||
.foregroundColor(.primary)
|
||||
Text(tag.formattedDate)
|
||||
.font(.scaledFootnote)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}.onDelete { indexes in
|
||||
if let index = indexes.first {
|
||||
context.delete(tags[index])
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("settings.general.recent-tags")
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.toolbar {
|
||||
EditButton()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import Models
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
struct RemoteTimelinesSettingView: View {
|
||||
@Environment(\.modelContext) private var context
|
||||
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
ForEach(localTimelines) { timeline in
|
||||
Text(timeline.instance)
|
||||
}.onDelete { indexes in
|
||||
if let index = indexes.first {
|
||||
context.delete(localTimelines[index])
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
Button {
|
||||
routerPath.presentedSheet = .addRemoteLocalTimeline
|
||||
} label: {
|
||||
Label("settings.timeline.add", systemImage: "badge.plus.radiowaves.right")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("settings.general.remote-timelines")
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.toolbar {
|
||||
EditButton()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@ import Timeline
|
|||
@MainActor
|
||||
struct SettingsTabs: View {
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@Environment(\.modelContext) private var context
|
||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||
|
||||
@Environment(PushNotificationsService.self) private var pushNotifications
|
||||
|
@ -32,10 +31,9 @@ struct SettingsTabs: View {
|
|||
@Binding var popToRootTab: Tab
|
||||
|
||||
let isModal: Bool
|
||||
|
||||
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
|
||||
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
||||
|
||||
|
||||
@State private var startingPoint: SettingsStartingPoint? = nil
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routerPath.path) {
|
||||
Form {
|
||||
|
@ -47,27 +45,53 @@ struct SettingsTabs: View {
|
|||
}
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.navigationTitle(Text("settings.title"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbar {
|
||||
if UIDevice.current.userInterfaceIdiom == .phone || isModal {
|
||||
ToolbarItem {
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Text("action.done").bold()
|
||||
.navigationTitle(Text("settings.title"))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.toolbar {
|
||||
if isModal {
|
||||
ToolbarItem {
|
||||
Button {
|
||||
dismiss()
|
||||
} label: {
|
||||
Text("action.done").bold()
|
||||
}
|
||||
}
|
||||
}
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn, !isModal {
|
||||
SecondaryColumnToolbarItem()
|
||||
}
|
||||
}
|
||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn {
|
||||
SecondaryColumnToolbarItem()
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
.onAppear {
|
||||
startingPoint = RouterPath.settingsStartingPoint
|
||||
RouterPath.settingsStartingPoint = nil
|
||||
}
|
||||
.navigationDestination(item: $startingPoint) { targetView in
|
||||
switch targetView {
|
||||
case .display:
|
||||
DisplaySettingsView()
|
||||
case .haptic:
|
||||
HapticSettingsView()
|
||||
case .remoteTimelines:
|
||||
RemoteTimelinesSettingView()
|
||||
case .tagGroups:
|
||||
TagsGroupSettingView()
|
||||
case .recentTags:
|
||||
RecenTagsSettingView()
|
||||
case .content:
|
||||
ContentSettingsView()
|
||||
case .swipeActions:
|
||||
SwipeActionsSettingsView()
|
||||
case .tabAndSidebarEntries:
|
||||
EmptyView()
|
||||
case .translation:
|
||||
TranslationSettingsView()
|
||||
}
|
||||
}
|
||||
}
|
||||
.withAppRouter()
|
||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||
}
|
||||
.onAppear {
|
||||
routerPath.client = client
|
||||
|
@ -101,7 +125,7 @@ struct SettingsTabs: View {
|
|||
.tint(.red)
|
||||
}
|
||||
}
|
||||
AppAccountView(viewModel: .init(appAccount: account))
|
||||
AppAccountView(viewModel: .init(appAccount: account), isParentPresented: .constant(false))
|
||||
}
|
||||
}
|
||||
.onDelete { indexSet in
|
||||
|
@ -149,12 +173,15 @@ struct SettingsTabs: View {
|
|||
Label("settings.general.haptic", systemImage: "waveform.path")
|
||||
}
|
||||
}
|
||||
NavigationLink(destination: remoteLocalTimelinesView) {
|
||||
NavigationLink(destination: RemoteTimelinesSettingView()) {
|
||||
Label("settings.general.remote-timelines", systemImage: "dot.radiowaves.right")
|
||||
}
|
||||
NavigationLink(destination: tagGroupsView) {
|
||||
NavigationLink(destination: TagsGroupSettingView()) {
|
||||
Label("timeline.filter.tag-groups", systemImage: "number")
|
||||
}
|
||||
NavigationLink(destination: RecenTagsSettingView()) {
|
||||
Label("settings.general.recent-tags", systemImage: "clock")
|
||||
}
|
||||
NavigationLink(destination: ContentSettingsView()) {
|
||||
Label("settings.general.content", systemImage: "rectangle.stack")
|
||||
}
|
||||
|
@ -165,6 +192,10 @@ struct SettingsTabs: View {
|
|||
NavigationLink(destination: TabbarEntriesSettingsView()) {
|
||||
Label("settings.general.tabbarEntries", systemImage: "platter.filled.bottom.iphone")
|
||||
}
|
||||
} else if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||
NavigationLink(destination: SidebarEntriesSettingsView()) {
|
||||
Label("settings.general.sidebarEntries", systemImage: "sidebar.squares.leading")
|
||||
}
|
||||
}
|
||||
NavigationLink(destination: TranslationSettingsView()) {
|
||||
Label("settings.general.translate", systemImage: "captions.bubble")
|
||||
|
@ -300,73 +331,6 @@ struct SettingsTabs: View {
|
|||
}
|
||||
}
|
||||
|
||||
private var tagGroupsView: some View {
|
||||
Form {
|
||||
ForEach(tagGroups) { group in
|
||||
Label(group.title, systemImage: group.symbolName)
|
||||
.onTapGesture {
|
||||
routerPath.presentedSheet = .editTagGroup(tagGroup: group, onSaved: nil)
|
||||
}
|
||||
}
|
||||
.onDelete { indexes in
|
||||
if let index = indexes.first {
|
||||
context.delete(tagGroups[index])
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
Button {
|
||||
routerPath.presentedSheet = .addTagGroup
|
||||
} label: {
|
||||
Label("timeline.filter.add-tag-groups", systemImage: "plus")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("timeline.filter.tag-groups")
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.toolbar {
|
||||
EditButton()
|
||||
}
|
||||
}
|
||||
|
||||
private var remoteLocalTimelinesView: some View {
|
||||
Form {
|
||||
ForEach(localTimelines) { timeline in
|
||||
Text(timeline.instance)
|
||||
}.onDelete { indexes in
|
||||
if let index = indexes.first {
|
||||
context.delete(localTimelines[index])
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
Button {
|
||||
routerPath.presentedSheet = .addRemoteLocalTimeline
|
||||
} label: {
|
||||
Label("settings.timeline.add", systemImage: "badge.plus.radiowaves.right")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("settings.general.remote-timelines")
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.toolbar {
|
||||
EditButton()
|
||||
}
|
||||
}
|
||||
|
||||
private var cacheSection: some View {
|
||||
Section("settings.section.cache") {
|
||||
if cachedRemoved {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
struct SidebarEntriesSettingsView: View {
|
||||
@Environment(Theme.self) private var theme
|
||||
@Environment(UserPreferences.self) private var userPreferences
|
||||
|
||||
@State private var sidebarTabs = SidebarTabs.shared
|
||||
|
||||
var body: some View {
|
||||
@Bindable var userPreferences = userPreferences
|
||||
Form {
|
||||
Section {
|
||||
ForEach($sidebarTabs.tabs, id: \.tab) { $tab in
|
||||
if tab.tab != .profile && tab.tab != .settings {
|
||||
Toggle(isOn: $tab.enabled) {
|
||||
tab.tab.label
|
||||
}
|
||||
}
|
||||
}
|
||||
.onMove(perform: move)
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.environment(\.editMode, .constant(.active))
|
||||
.navigationTitle("settings.general.sidebarEntries")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
func move(from source: IndexSet, to destination: Int) {
|
||||
sidebarTabs.tabs.move(fromOffsets: source, toOffset: destination)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import RevenueCat
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -70,24 +69,24 @@ struct SupportAppView: View {
|
|||
}
|
||||
.navigationTitle("settings.support.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.alert("settings.support.alert.title", isPresented: $purchaseSuccessDisplayed, actions: {
|
||||
Button { purchaseSuccessDisplayed = false } label: { Text("alert.button.ok") }
|
||||
}, message: {
|
||||
Text("settings.support.alert.message")
|
||||
})
|
||||
.alert("alert.error", isPresented: $purchaseErrorDisplayed, actions: {
|
||||
Button { purchaseErrorDisplayed = false } label: { Text("alert.button.ok") }
|
||||
}, message: {
|
||||
Text("settings.support.alert.error.message")
|
||||
})
|
||||
.onAppear {
|
||||
loadingProducts = true
|
||||
fetchStoreProducts()
|
||||
refreshUserInfo()
|
||||
}
|
||||
.alert("settings.support.alert.title", isPresented: $purchaseSuccessDisplayed, actions: {
|
||||
Button { purchaseSuccessDisplayed = false } label: { Text("alert.button.ok") }
|
||||
}, message: {
|
||||
Text("settings.support.alert.message")
|
||||
})
|
||||
.alert("alert.error", isPresented: $purchaseErrorDisplayed, actions: {
|
||||
Button { purchaseErrorDisplayed = false } label: { Text("alert.button.ok") }
|
||||
}, message: {
|
||||
Text("settings.support.alert.error.message")
|
||||
})
|
||||
.onAppear {
|
||||
loadingProducts = true
|
||||
fetchStoreProducts()
|
||||
refreshUserInfo()
|
||||
}
|
||||
}
|
||||
|
||||
private func purchase(product: StoreProduct) async {
|
||||
|
@ -280,6 +279,5 @@ struct SupportAppView: View {
|
|||
}
|
||||
.redacted(reason: .placeholder)
|
||||
.allowsHitTesting(false)
|
||||
.shimmering()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ struct SwipeActionsSettingsView: View {
|
|||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
|
||||
Section {
|
||||
Picker(selection: $userPreferences.swipeActionsIconStyle, label: Text("settings.swipeactions.icon-style")) {
|
||||
ForEach(UserPreferences.SwipeActionsIconStyle.allCases, id: \.rawValue) { style in
|
||||
|
@ -70,8 +70,8 @@ struct SwipeActionsSettingsView: View {
|
|||
}
|
||||
.navigationTitle("settings.swipeactions.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import SwiftUI
|
|||
struct TabbarEntriesSettingsView: View {
|
||||
@Environment(Theme.self) private var theme
|
||||
@Environment(UserPreferences.self) private var userPreferences
|
||||
|
||||
|
||||
@State private var tabs = iOSTabs.shared
|
||||
|
||||
var body: some View {
|
||||
|
@ -42,7 +42,7 @@ struct TabbarEntriesSettingsView: View {
|
|||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
|
||||
Section {
|
||||
Toggle("settings.display.show-tab-label", isOn: $userPreferences.showiPhoneTabLabel)
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ struct TabbarEntriesSettingsView: View {
|
|||
}
|
||||
.navigationTitle("settings.general.tabbarEntries")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
50
IceCubesApp/App/Tabs/Settings/TagsGroupSettingView.swift
Normal file
|
@ -0,0 +1,50 @@
|
|||
import DesignSystem
|
||||
import Env
|
||||
import Models
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
struct TagsGroupSettingView: View {
|
||||
@Environment(\.modelContext) private var context
|
||||
|
||||
@Environment(RouterPath.self) private var routerPath
|
||||
@Environment(Theme.self) private var theme
|
||||
|
||||
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
||||
|
||||
var body: some View {
|
||||
Form {
|
||||
ForEach(tagGroups) { group in
|
||||
Label(group.title, systemImage: group.symbolName)
|
||||
.onTapGesture {
|
||||
routerPath.presentedSheet = .editTagGroup(tagGroup: group, onSaved: nil)
|
||||
}
|
||||
}
|
||||
.onDelete { indexes in
|
||||
if let index = indexes.first {
|
||||
context.delete(tagGroups[index])
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
Button {
|
||||
routerPath.presentedSheet = .addTagGroup
|
||||
} label: {
|
||||
Label("timeline.filter.add-tag-groups", systemImage: "plus")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.navigationTitle("timeline.filter.tag-groups")
|
||||
.scrollContentBackground(.hidden)
|
||||
#if !os(visionOS)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.toolbar {
|
||||
EditButton()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,20 +11,17 @@ struct TranslationSettingsView: View {
|
|||
|
||||
var body: some View {
|
||||
Form {
|
||||
deepLToggle
|
||||
if preferences.alwaysUseDeepl {
|
||||
translationSelector
|
||||
if preferences.preferredTranslationType == .useDeepl {
|
||||
Section("settings.translation.user-api-key") {
|
||||
deepLPicker
|
||||
SecureField("settings.translation.user-api-key", text: $apiKey)
|
||||
.textContentType(.password)
|
||||
}
|
||||
.onAppear {
|
||||
readValue()
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
|
||||
if apiKey.isEmpty {
|
||||
Section {
|
||||
Link(destination: URL(string: "https://www.deepl.com/pro-api")!) {
|
||||
|
@ -37,30 +34,51 @@ struct TranslationSettingsView: View {
|
|||
#endif
|
||||
}
|
||||
}
|
||||
backgroundAPIKey
|
||||
autoDetectSection
|
||||
}
|
||||
.navigationTitle("settings.translation.navigation-title")
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
#endif
|
||||
.onChange(of: apiKey) {
|
||||
writeNewValue()
|
||||
}
|
||||
.onAppear(perform: updatePrefs)
|
||||
.onChange(of: apiKey) {
|
||||
writeNewValue()
|
||||
}
|
||||
.onAppear(perform: updatePrefs)
|
||||
.onAppear(perform: readValue)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var deepLToggle: some View {
|
||||
private var translationSelector: some View {
|
||||
@Bindable var preferences = preferences
|
||||
Toggle(isOn: $preferences.alwaysUseDeepl) {
|
||||
Text("settings.translation.always-deepl")
|
||||
Picker("Translation Service", selection: $preferences.preferredTranslationType) {
|
||||
ForEach(allTTCases, id: \.self) { type in
|
||||
Text(type.description).tag(type)
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
var allTTCases: [TranslationType] {
|
||||
TranslationType.allCases.filter { type in
|
||||
if type != .useApple {
|
||||
return true
|
||||
}
|
||||
#if canImport(_Translation_SwiftUI)
|
||||
if #available(iOS 17.4, *) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
#else
|
||||
return false
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var deepLPicker: some View {
|
||||
@Bindable var preferences = preferences
|
||||
|
@ -80,6 +98,34 @@ struct TranslationSettingsView: View {
|
|||
} footer: {
|
||||
Text("settings.translation.auto-detect-post-language-footer")
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var backgroundAPIKey: some View {
|
||||
if preferences.preferredTranslationType != .useDeepl,
|
||||
!apiKey.isEmpty
|
||||
{
|
||||
Section {
|
||||
Text("The DeepL API Key is still stored!")
|
||||
if preferences.preferredTranslationType == .useServerIfPossible {
|
||||
Text("It can however still be used as a fallback for your instance's translation service.")
|
||||
}
|
||||
Button(role: .destructive) {
|
||||
withAnimation {
|
||||
writeNewValue(value: "")
|
||||
readValue()
|
||||
}
|
||||
} label: {
|
||||
Text("action.delete")
|
||||
}
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private func writeNewValue() {
|
||||
|
@ -91,11 +137,7 @@ struct TranslationSettingsView: View {
|
|||
}
|
||||
|
||||
private func readValue() {
|
||||
if let apiKey = DeepLUserAPIHandler.readIfAllowed() {
|
||||
self.apiKey = apiKey
|
||||
} else {
|
||||
apiKey = ""
|
||||
}
|
||||
apiKey = DeepLUserAPIHandler.readKey()
|
||||
}
|
||||
|
||||
private func updatePrefs() {
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
import Account
|
||||
import AppIntents
|
||||
import DesignSystem
|
||||
import Explore
|
||||
import Foundation
|
||||
import Status
|
||||
import StatusKit
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
||||
enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||
case timeline, notifications, mentions, explore, messages, settings, other
|
||||
case trending, federated, local
|
||||
case profile
|
||||
case bookmarks
|
||||
case favorites
|
||||
case post
|
||||
case followedTags
|
||||
case lists
|
||||
case links
|
||||
|
||||
nonisolated var id: Int {
|
||||
rawValue
|
||||
|
@ -21,15 +26,8 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
|||
[.timeline, .settings]
|
||||
}
|
||||
|
||||
static func loggedInTabs() -> [Tab] {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad ||
|
||||
UIDevice.current.userInterfaceIdiom == .mac {
|
||||
[.timeline, .trending, .federated, .local, .notifications, .mentions, .explore, .messages, .bookmarks, .favorites, .settings]
|
||||
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
||||
[.profile, .timeline, .trending, .federated, .local, .notifications, .mentions, .explore, .messages, .settings]
|
||||
} else {
|
||||
[.timeline, .notifications, .explore, .messages, .profile]
|
||||
}
|
||||
static func visionOSTab() -> [Tab] {
|
||||
[.profile, .timeline, .notifications, .mentions, .explore, .post, .settings]
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
@ -63,6 +61,18 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
|||
NavigationTab {
|
||||
AccountStatusesListView(mode: .favorites)
|
||||
}
|
||||
case .followedTags:
|
||||
NavigationTab {
|
||||
FollowedTagsListView()
|
||||
}
|
||||
case .lists:
|
||||
NavigationTab {
|
||||
ListsListView()
|
||||
}
|
||||
case .links:
|
||||
NavigationTab { TrendingLinksListView(cards: []) }
|
||||
case .post:
|
||||
VStack {}
|
||||
case .other:
|
||||
EmptyView()
|
||||
}
|
||||
|
@ -70,33 +80,47 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
|||
|
||||
@ViewBuilder
|
||||
var label: some View {
|
||||
if self != .other {
|
||||
Label(title, systemImage: iconName)
|
||||
}
|
||||
}
|
||||
|
||||
var title: LocalizedStringKey {
|
||||
switch self {
|
||||
case .timeline:
|
||||
Label("tab.timeline", systemImage: iconName)
|
||||
"tab.timeline"
|
||||
case .trending:
|
||||
Label("tab.trending", systemImage: iconName)
|
||||
"tab.trending"
|
||||
case .local:
|
||||
Label("tab.local", systemImage: iconName)
|
||||
"tab.local"
|
||||
case .federated:
|
||||
Label("tab.federated", systemImage: iconName)
|
||||
"tab.federated"
|
||||
case .notifications:
|
||||
Label("tab.notifications", systemImage: iconName)
|
||||
"tab.notifications"
|
||||
case .mentions:
|
||||
Label("tab.mentions", systemImage: iconName)
|
||||
"tab.mentions"
|
||||
case .explore:
|
||||
Label("tab.explore", systemImage: iconName)
|
||||
"tab.explore"
|
||||
case .messages:
|
||||
Label("tab.messages", systemImage: iconName)
|
||||
"tab.messages"
|
||||
case .settings:
|
||||
Label("tab.settings", systemImage: iconName)
|
||||
"tab.settings"
|
||||
case .profile:
|
||||
Label("tab.profile", systemImage: iconName)
|
||||
"tab.profile"
|
||||
case .bookmarks:
|
||||
Label("accessibility.tabs.profile.picker.bookmarks", systemImage: iconName)
|
||||
"accessibility.tabs.profile.picker.bookmarks"
|
||||
case .favorites:
|
||||
Label("accessibility.tabs.profile.picker.favorites", systemImage: iconName)
|
||||
"accessibility.tabs.profile.picker.favorites"
|
||||
case .post:
|
||||
"menu.new-post"
|
||||
case .followedTags:
|
||||
"timeline.filter.tags"
|
||||
case .lists:
|
||||
"timeline.filter.lists"
|
||||
case .links:
|
||||
"explore.section.trending.links"
|
||||
case .other:
|
||||
EmptyView()
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,18 +150,73 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable {
|
|||
"bookmark"
|
||||
case .favorites:
|
||||
"star"
|
||||
case .post:
|
||||
"square.and.pencil"
|
||||
case .followedTags:
|
||||
"tag"
|
||||
case .lists:
|
||||
"list.bullet"
|
||||
case .links:
|
||||
"newspaper"
|
||||
case .other:
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
class SidebarTabs {
|
||||
struct SidedebarTab: Hashable, Codable {
|
||||
let tab: Tab
|
||||
var enabled: Bool
|
||||
}
|
||||
|
||||
class Storage {
|
||||
@AppStorage("sidebar_tabs") var tabs: [SidedebarTab] = [
|
||||
.init(tab: .timeline, enabled: true),
|
||||
.init(tab: .trending, enabled: true),
|
||||
.init(tab: .federated, enabled: true),
|
||||
.init(tab: .local, enabled: true),
|
||||
.init(tab: .notifications, enabled: true),
|
||||
.init(tab: .mentions, enabled: true),
|
||||
.init(tab: .messages, enabled: true),
|
||||
.init(tab: .explore, enabled: true),
|
||||
.init(tab: .bookmarks, enabled: true),
|
||||
.init(tab: .favorites, enabled: true),
|
||||
.init(tab: .followedTags, enabled: true),
|
||||
.init(tab: .lists, enabled: true),
|
||||
|
||||
.init(tab: .settings, enabled: true),
|
||||
.init(tab: .profile, enabled: true),
|
||||
]
|
||||
}
|
||||
|
||||
private let storage = Storage()
|
||||
public static let shared = SidebarTabs()
|
||||
|
||||
var tabs: [SidedebarTab] {
|
||||
didSet {
|
||||
storage.tabs = tabs
|
||||
}
|
||||
}
|
||||
|
||||
func isEnabled(_ tab: Tab) -> Bool {
|
||||
tabs.first(where: { $0.tab.id == tab.id })?.enabled == true
|
||||
}
|
||||
|
||||
private init() {
|
||||
tabs = storage.tabs
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@Observable
|
||||
class iOSTabs {
|
||||
enum TabEntries: String {
|
||||
case first, second, third, fourth, fifth
|
||||
}
|
||||
|
||||
|
||||
class Storage {
|
||||
@AppStorage(TabEntries.first.rawValue) var firstTab = Tab.timeline
|
||||
@AppStorage(TabEntries.second.rawValue) var secondTab = Tab.notifications
|
||||
|
@ -145,44 +224,44 @@ class iOSTabs {
|
|||
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = Tab.messages
|
||||
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = Tab.profile
|
||||
}
|
||||
|
||||
|
||||
private let storage = Storage()
|
||||
public static let shared = iOSTabs()
|
||||
|
||||
|
||||
var tabs: [Tab] {
|
||||
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
||||
}
|
||||
|
||||
|
||||
var firstTab: Tab {
|
||||
didSet {
|
||||
storage.firstTab = firstTab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var secondTab: Tab {
|
||||
didSet {
|
||||
storage.secondTab = secondTab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var thirdTab: Tab {
|
||||
didSet {
|
||||
storage.thirdTab = thirdTab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var fourthTab: Tab {
|
||||
didSet {
|
||||
storage.fourthTab = fourthTab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var fifthTab: Tab {
|
||||
didSet {
|
||||
storage.fifthTab = fifthTab
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private init() {
|
||||
firstTab = storage.firstTab
|
||||
secondTab = storage.secondTab
|
||||
|
|
|
@ -5,7 +5,6 @@ import Models
|
|||
import Network
|
||||
import NukeUI
|
||||
import SFSafeSymbols
|
||||
import Shimmer
|
||||
import SwiftData
|
||||
import SwiftUI
|
||||
|
||||
|
@ -39,7 +38,9 @@ struct EditTagGroupView: View {
|
|||
focusedField: $focusedField
|
||||
)
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
|
||||
Section("add-tag-groups.edit.tags") {
|
||||
TagsInputView(
|
||||
|
@ -48,7 +49,9 @@ struct EditTagGroupView: View {
|
|||
focusedField: $focusedField
|
||||
)
|
||||
}
|
||||
#if !os(visionOS)
|
||||
.listRowBackground(theme.primaryBackgroundColor)
|
||||
#endif
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
.navigationTitle(
|
||||
|
@ -58,22 +61,20 @@ struct EditTagGroupView: View {
|
|||
)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.interactively)
|
||||
#endif
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button("action.cancel", action: { dismiss() })
|
||||
.toolbar {
|
||||
CancelToolbarItem()
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button("action.save", action: { save() })
|
||||
.disabled(!tagGroup.isValid)
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button("action.save", action: { save() })
|
||||
.disabled(!tagGroup.isValid)
|
||||
.onAppear {
|
||||
focusedField = .title
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
focusedField = .title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +104,7 @@ struct AddTagGroupView_Previews: PreviewProvider {
|
|||
let container = try? ModelContainer(for: TagGroup.self, configurations: ModelConfiguration())
|
||||
|
||||
// need to use `sheet` to show `symbolsSuggestionView` in preview
|
||||
return Text("parent view for EditTagGroupView")
|
||||
return Text(verbatim: "parent view for EditTagGroupView")
|
||||
.sheet(isPresented: .constant(true)) {
|
||||
EditTagGroupView()
|
||||
.withEnvironments()
|
||||
|
|
|
@ -4,7 +4,6 @@ import Env
|
|||
import Models
|
||||
import Network
|
||||
import NukeUI
|
||||
import Shimmer
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
|
@ -53,31 +52,29 @@ struct AddRemoteTimelineView: View {
|
|||
.navigationTitle("timeline.add-remote.title")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#if !os(visionOS)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(theme.secondaryBackgroundColor)
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
#endif
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
Button("action.cancel", action: { dismiss() })
|
||||
.toolbar {
|
||||
CancelToolbarItem()
|
||||
}
|
||||
}
|
||||
.onChange(of: instanceName) { _, newValue in
|
||||
instanceNamePublisher.send(newValue)
|
||||
}
|
||||
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
|
||||
Task {
|
||||
let client = Client(server: newValue)
|
||||
instance = try? await client.get(endpoint: Instances.instance)
|
||||
.onChange(of: instanceName) { _, newValue in
|
||||
instanceNamePublisher.send(newValue)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
isInstanceURLFieldFocused = true
|
||||
let client = InstanceSocialClient()
|
||||
Task {
|
||||
instances = await client.fetchInstances(keyword: instanceName)
|
||||
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
|
||||
Task {
|
||||
let client = Client(server: newValue)
|
||||
instance = try? await client.get(endpoint: Instances.instance)
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
isInstanceURLFieldFocused = true
|
||||
let client = InstanceSocialClient()
|
||||
Task {
|
||||
instances = await client.fetchInstances(keyword: instanceName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ struct TimelineTab: View {
|
|||
.toolbar {
|
||||
toolbarView
|
||||
}
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||
.id(client.id)
|
||||
}
|
||||
.onAppear {
|
||||
|
@ -94,8 +94,8 @@ struct TimelineTab: View {
|
|||
lastTimelineFilter = newValue
|
||||
}
|
||||
switch newValue {
|
||||
case let .tagGroup(title, _):
|
||||
if let group = tagGroups.first(where: { $0.title == title}) {
|
||||
case let .tagGroup(title, _, _):
|
||||
if let group = tagGroups.first(where: { $0.title == title }) {
|
||||
selectedTagGroup = group
|
||||
}
|
||||
default:
|
||||
|
@ -123,13 +123,14 @@ struct TimelineTab: View {
|
|||
|
||||
@ViewBuilder
|
||||
private var timelineFilterButton: some View {
|
||||
latestOrResumeButtons
|
||||
pinMenuButton
|
||||
headerGroup
|
||||
timelineFiltersButtons
|
||||
listsFiltersButons
|
||||
tagsFiltersButtons
|
||||
localTimelinesFiltersButtons
|
||||
tagGroupsFiltersButtons
|
||||
Divider()
|
||||
contentFilterButton
|
||||
}
|
||||
|
||||
private var addAccountButton: some View {
|
||||
|
@ -184,14 +185,16 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var latestOrResumeButtons: some View {
|
||||
if timeline.supportNewestPagination {
|
||||
Button {
|
||||
timeline = .latest
|
||||
} label: {
|
||||
Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName())
|
||||
private var headerGroup: some View {
|
||||
ControlGroup {
|
||||
if timeline.supportNewestPagination {
|
||||
Button {
|
||||
timeline = .latest
|
||||
} label: {
|
||||
Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName())
|
||||
}
|
||||
}
|
||||
if timeline == .home {
|
||||
Button {
|
||||
|
@ -203,13 +206,13 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
Divider()
|
||||
pinButton
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var pinMenuButton: some View {
|
||||
let index = pinnedFilters.firstIndex(where: { $0.id == timeline.id})
|
||||
private var pinButton: some View {
|
||||
let index = pinnedFilters.firstIndex(where: { $0.id == timeline.id })
|
||||
Button {
|
||||
withAnimation {
|
||||
if let index {
|
||||
|
@ -219,16 +222,14 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
} label: {
|
||||
if index != nil {
|
||||
if index != nil {
|
||||
Label("status.action.unpin", systemImage: "pin.slash")
|
||||
} else {
|
||||
Label("status.action.pin", systemImage: "pin")
|
||||
}
|
||||
}
|
||||
|
||||
Divider()
|
||||
}
|
||||
|
||||
|
||||
private var timelineFiltersButtons: some View {
|
||||
ForEach(TimelineFilter.availableTimeline(client: client), id: \.self) { timeline in
|
||||
Button {
|
||||
|
@ -238,27 +239,25 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var listsFiltersButons: some View {
|
||||
if !currentAccount.lists.isEmpty {
|
||||
Menu("timeline.filter.lists") {
|
||||
ForEach(currentAccount.sortedLists) { list in
|
||||
Button {
|
||||
timeline = .list(list: list)
|
||||
} label: {
|
||||
Label(list.title, systemImage: "list.bullet")
|
||||
}
|
||||
}
|
||||
Menu("timeline.filter.lists") {
|
||||
Button {
|
||||
routerPath.presentedSheet = .listCreate
|
||||
} label: {
|
||||
Label("account.list.create", systemImage: "plus")
|
||||
}
|
||||
ForEach(currentAccount.sortedLists) { list in
|
||||
Button {
|
||||
routerPath.presentedSheet = .listCreate
|
||||
timeline = .list(list: list)
|
||||
} label: {
|
||||
Label("account.list.create", systemImage: "plus")
|
||||
Label(list.title, systemImage: "list.bullet")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ViewBuilder
|
||||
private var tagsFiltersButtons: some View {
|
||||
if !currentAccount.tags.isEmpty {
|
||||
|
@ -273,7 +272,7 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var localTimelinesFiltersButtons: some View {
|
||||
Menu("timeline.filter.local") {
|
||||
ForEach(localTimelines) { remoteLocal in
|
||||
|
@ -292,12 +291,12 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var tagGroupsFiltersButtons: some View {
|
||||
Menu("timeline.filter.tag-groups") {
|
||||
ForEach(tagGroups) { group in
|
||||
Button {
|
||||
timeline = .tagGroup(title: group.title, tags: group.tags)
|
||||
timeline = .tagGroup(title: group.title, tags: group.tags, symbolName: group.symbolName)
|
||||
} label: {
|
||||
VStack {
|
||||
let icon = group.symbolName.isEmpty ? "number" : group.symbolName
|
||||
|
@ -314,6 +313,14 @@ struct TimelineTab: View {
|
|||
}
|
||||
}
|
||||
|
||||
private var contentFilterButton: some View {
|
||||
Button(action: {
|
||||
routerPath.presentedSheet = .timelineContentFilter
|
||||
}, label: {
|
||||
Label("timeline.content-filter.title", systemSymbol: .line3HorizontalDecrease)
|
||||
})
|
||||
}
|
||||
|
||||
private func resetTimelineFilter() {
|
||||
if client.isAuth, canFilterTimeline {
|
||||
timeline = lastTimelineFilter
|
||||
|
|
|
@ -1,23 +1,39 @@
|
|||
import SwiftUI
|
||||
import Env
|
||||
import AppAccount
|
||||
import DesignSystem
|
||||
import Env
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
struct ToolbarTab: ToolbarContent {
|
||||
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||
|
||||
|
||||
@Environment(UserPreferences.self) private var userPreferences
|
||||
|
||||
|
||||
@Binding var routerPath: RouterPath
|
||||
|
||||
|
||||
var body: some ToolbarContent {
|
||||
if !isSecondaryColumn {
|
||||
ToolbarItem(placement: .topBarLeading) {
|
||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||
Button {
|
||||
withAnimation {
|
||||
userPreferences.isSidebarExpanded.toggle()
|
||||
}
|
||||
} label: {
|
||||
if userPreferences.isSidebarExpanded {
|
||||
Image(systemName: "sidebar.squares.left")
|
||||
} else {
|
||||
Image(systemName: "sidebar.left")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
statusEditorToolbarItem(routerPath: routerPath,
|
||||
visibility: userPreferences.postVisibility)
|
||||
if UIDevice.current.userInterfaceIdiom != .pad ||
|
||||
(UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact) {
|
||||
(UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact)
|
||||
{
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
AppAccountsSelectorView(routerPath: routerPath)
|
||||
}
|
||||
|
|
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/1024.png
Normal file
After Width: | Height: | Size: 991 KiB |
Before Width: | Height: | Size: 156 KiB |
|
@ -1,67 +1,67 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "AppIcon.png",
|
||||
"filename" : "1024.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-16.png",
|
||||
"filename" : "macos16.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-32.png",
|
||||
"filename" : "macos32 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "16x16"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-32 1.png",
|
||||
"filename" : "macos32.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-64.png",
|
||||
"filename" : "macos64.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "32x32"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-128.png",
|
||||
"filename" : "macos128.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-256 1.png",
|
||||
"filename" : "mac256 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "128x128"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-256.png",
|
||||
"filename" : "mac256.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-512 1.png",
|
||||
"filename" : "macOS512 1.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "256x256"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-512.png",
|
||||
"filename" : "macOS512.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "1x",
|
||||
"size" : "512x512"
|
||||
},
|
||||
{
|
||||
"filename" : "Icon-1024.png",
|
||||
"filename" : "macOS1024.png",
|
||||
"idiom" : "mac",
|
||||
"scale" : "2x",
|
||||
"size" : "512x512"
|
||||
|
|
Before Width: | Height: | Size: 501 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 734 B |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 147 KiB |
Before Width: | Height: | Size: 5.5 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/mac256 1.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/mac256.png
Normal file
After Width: | Height: | Size: 79 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macOS1024.png
Normal file
After Width: | Height: | Size: 973 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macOS512 1.png
Normal file
After Width: | Height: | Size: 262 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macOS512.png
Normal file
After Width: | Height: | Size: 262 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macos128.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macos16.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macos32 1.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macos32.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/macos64.png
Normal file
After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 764 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Back.png",
|
||||
"filename" : "Background.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Front.png",
|
||||
"filename" : "Layer 1.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 543 KiB |
After Width: | Height: | Size: 549 KiB |
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Middle.png",
|
||||
"idiom" : "vision",
|
||||
"scale" : "2x"
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 991 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "AppIcon-fs8.png",
|
||||
"filename" : "1024.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 846 KiB After Width: | Height: | Size: 846 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon.png",
|
||||
"filename" : "1024.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 615 KiB |
After Width: | Height: | Size: 565 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Dimillian_Ice_Cubes_in_a_glass_neon_style_glyph_retro_4b25c3a5-7ae2-401b-9b2f-17c9832e175a.png",
|
||||
"filename" : "AppIconAlternate10.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Dimillian_Ice_Cubes_in_a_glass_neon_style_glyph_retro_7ca60288-3e96-43a3-a88b-f4c882ac2183.png",
|
||||
"filename" : "icon15.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 406 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "Dimillian_Ice_Cubes_in_a_glass_neon_style_glyph_retro_2338f943-14f9-4639-aabf-70dc18cf4d52.png",
|
||||
"filename" : "icon16.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 401 KiB After Width: | Height: | Size: 401 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon13.png",
|
||||
"filename" : "icon17.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 259 KiB After Width: | Height: | Size: 259 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon14.png",
|
||||
"filename" : "icon18.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 565 KiB |
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 274 KiB |
After Width: | Height: | Size: 305 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon15.png",
|
||||
"filename" : "AppIconAlternate15.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon16.png",
|
||||
"filename" : "icon.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 242 KiB After Width: | Height: | Size: 242 KiB |
Before Width: | Height: | Size: 268 KiB After Width: | Height: | Size: 268 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon17.png",
|
||||
"filename" : "Alternate43-fs8.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 596 KiB After Width: | Height: | Size: 596 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon18.png",
|
||||
"filename" : "Alternate44-fs8.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|
Before Width: | Height: | Size: 624 KiB After Width: | Height: | Size: 624 KiB |
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "icon.png",
|
||||
"filename" : "Alternate45-fs8.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
|
|