Compare commits
366 commits
Author | SHA1 | Date | |
---|---|---|---|
|
27b3856e05 | ||
|
93beb2fbd9 | ||
|
04344ba834 | ||
|
f220837309 | ||
|
97c9a1fcf4 | ||
|
b4900989fa | ||
|
8b89eb61cc | ||
|
90d97885cd | ||
|
974d3f1804 | ||
|
f0c91784d0 | ||
|
9fbd0a6a2f | ||
|
70eb781407 | ||
|
56f0afb062 | ||
|
3be69aa4a7 | ||
|
6e766a3fa8 | ||
|
9af485b2be | ||
|
71027e2cc3 | ||
|
4338e0a355 | ||
|
df19135e19 | ||
|
12b6c1af36 | ||
|
db7155423a | ||
|
7eeaf4d902 | ||
|
b19a5706e2 | ||
|
a1ce85b188 | ||
|
009150bc3e | ||
|
23960d6d0f | ||
|
4dd4968bb2 | ||
|
b0846c9a3d | ||
|
7cef1c5786 | ||
|
a167bcdf28 | ||
|
d2eca1d646 | ||
|
9ec6a4ef66 | ||
|
576b52e8c8 | ||
|
46f481aabd | ||
|
81d5d4396f | ||
|
f610c3f047 | ||
|
7a35779b29 | ||
|
e4d1196301 | ||
|
93421c56d9 | ||
|
0b7c6a799f | ||
|
8f71f6649a | ||
|
122e57d8ac | ||
|
594fb3ea07 | ||
|
2f1632b950 | ||
|
c1dfb0a085 | ||
|
ae1bfbeb45 | ||
|
6d289ebd09 | ||
|
be2939b13c | ||
|
491090e373 | ||
|
7c5f2aea81 | ||
|
24f8982bd4 | ||
|
7b67ba0294 | ||
|
698edc4d58 | ||
|
9d5d341764 | ||
|
896c031ab0 | ||
|
c0b0a3ee1c | ||
|
30b9a95cac | ||
|
0a15f7ff1c | ||
|
8f7df06d21 | ||
|
6297a428a3 | ||
|
4cce9d6333 | ||
|
435f28dda9 | ||
|
904cd3dbd7 | ||
|
ce3e2d2344 | ||
|
5080a536db | ||
|
55cbd9ea6f | ||
|
24f77a99e1 | ||
|
45628b5a5f | ||
|
1b7720c9c4 | ||
|
199749b809 | ||
|
e0eed97bcf | ||
|
f80fca91e2 | ||
|
dc85557d40 | ||
|
412f475d1d | ||
|
dfbbb84e9d | ||
|
83bf872cca | ||
|
8c6d2bee7f | ||
|
824b2de23f | ||
|
48febd628f | ||
|
dd1a4585e0 | ||
|
1ad4a245f3 | ||
|
9d11814e49 | ||
|
56869e3a2f | ||
|
a737ac19e5 | ||
|
456d85eda2 | ||
|
4158f7c959 | ||
|
113c4f1c84 | ||
|
77bec1fae3 | ||
|
6f608efa7f | ||
|
6c9d9161dc | ||
|
a72f290038 | ||
|
2a3da72239 | ||
|
9fa19aa132 | ||
|
123f05538a | ||
|
719c023369 | ||
|
0338d54d81 | ||
|
6fa4ac6f79 | ||
|
cf494fd07a | ||
|
6766ed496d | ||
|
33c2646ea1 | ||
|
9af98c3921 | ||
|
4f9cb2e86a | ||
|
4c1ba2168d | ||
|
be02b2ea76 | ||
|
a3326c3fc2 | ||
|
563213d98f | ||
|
82338f815a | ||
|
7a9b6cc0e0 | ||
|
339e2ab1c3 | ||
|
f18f3e0e84 | ||
|
fc6b2129dd | ||
|
54768772b5 | ||
|
3f2fbeeec4 | ||
|
47b5fdf92e | ||
|
d320caaa4f | ||
|
fbff1d6dfe | ||
|
3c5c9adc03 | ||
|
5969e8a166 | ||
|
8a33b6c0d0 | ||
|
d7429c078f | ||
|
6f3f8e9dd0 | ||
|
b98a90ced6 | ||
|
fdb213e4bf | ||
|
4b8d7113f1 | ||
|
7b9cfc2863 | ||
|
478a788f87 | ||
|
2d04433783 | ||
|
59a333cc20 | ||
|
9bc9961f34 | ||
|
0af3732ea9 | ||
|
5960014da9 | ||
|
2ab52d3d3e | ||
|
cd60e0ce1a | ||
|
ff1d5733a0 | ||
|
9887a81ef0 | ||
|
f2ba08e1cc | ||
|
2b8bc2ecd3 | ||
|
513c686b64 | ||
|
aaeb9eaa36 | ||
|
02a8cb12e9 | ||
|
be54a58ae6 | ||
|
8e86e6d205 | ||
|
283e537c44 | ||
|
551697eb2c | ||
|
ab99ef9a0a | ||
|
02d73de113 | ||
|
375ea665b4 | ||
|
a88b9a7fd9 | ||
|
520315d50f | ||
|
1bbbdc8194 | ||
|
d36930b7af | ||
|
c06e3b59e4 | ||
|
8cca261e43 | ||
|
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 |
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"
|
|
@ -13,7 +13,7 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
|
|
||||||
// Sample code was sending this from a thread to another, let asume @Sendable for this
|
// Sample code was sending this from a thread to another, let asume @Sendable for this
|
||||||
extension NSExtensionContext: @unchecked Sendable {}
|
extension NSExtensionContext: @unchecked @retroactive Sendable {}
|
||||||
|
|
||||||
final class ActionRequestHandler: NSObject, NSExtensionRequestHandling, Sendable {
|
final class ActionRequestHandler: NSObject, NSExtensionRequestHandling, Sendable {
|
||||||
enum Error: Swift.Error {
|
enum Error: Swift.Error {
|
||||||
|
|
|
@ -26,8 +26,6 @@
|
||||||
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F24EEB729360C330042359D /* Preview Assets.xcassets */; };
|
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9F24EEB729360C330042359D /* Preview Assets.xcassets */; };
|
||||||
9F295540292B6C3400E0E81B /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F29553F292B6C3400E0E81B /* Timeline */; };
|
9F295540292B6C3400E0E81B /* Timeline in Frameworks */ = {isa = PBXBuildFile; productRef = 9F29553F292B6C3400E0E81B /* Timeline */; };
|
||||||
9F2A540729699698009B2D7C /* SupportAppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A540629699698009B2D7C /* SupportAppView.swift */; };
|
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 */; };
|
9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F2A540D2969A0B0009B2D7C /* StoreKit.framework */; };
|
||||||
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5410296A1429009B2D7C /* PushNotificationsView.swift */; };
|
9F2A5411296A1429009B2D7C /* PushNotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5410296A1429009B2D7C /* PushNotificationsView.swift */; };
|
||||||
9F2A5419296AB631009B2D7C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5418296AB631009B2D7C /* NotificationService.swift */; };
|
9F2A5419296AB631009B2D7C /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2A5418296AB631009B2D7C /* NotificationService.swift */; };
|
||||||
|
@ -44,6 +42,11 @@
|
||||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
||||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
||||||
9F35DB4C2952005C00B3281A /* MessagesTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4B2952005C00B3281A /* MessagesTab.swift */; };
|
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 */; };
|
9F38A7332ACEA26100DBCD66 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */; };
|
||||||
9F38A7342ACEA26100DBCD66 /* 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 */; };
|
9F38A7352ACEA26100DBCD66 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9F38A7322ACEA26100DBCD66 /* Localizable.xcstrings */; };
|
||||||
|
@ -54,6 +57,9 @@
|
||||||
9F4A48192976B21900A1A038 /* ProfileTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4A48182976B21900A1A038 /* ProfileTab.swift */; };
|
9F4A48192976B21900A1A038 /* ProfileTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F4A48182976B21900A1A038 /* ProfileTab.swift */; };
|
||||||
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F55C68C2955968700F94077 /* ExploreTab.swift */; };
|
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F55C68C2955968700F94077 /* ExploreTab.swift */; };
|
||||||
9F55C6902955993C00F94077 /* Explore in Frameworks */ = {isa = PBXBuildFile; productRef = 9F55C68F2955993C00F94077 /* Explore */; };
|
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 */; };
|
9F5E581929545BE700A53960 /* Env in Frameworks */ = {isa = PBXBuildFile; productRef = 9F5E581829545BE700A53960 /* Env */; };
|
||||||
9F6028562B3F36AE00476078 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028552B3F36AE00476078 /* AppView.swift */; };
|
9F6028562B3F36AE00476078 /* AppView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028552B3F36AE00476078 /* AppView.swift */; };
|
||||||
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028572B3F3B7600476078 /* ToolbarTab.swift */; };
|
9F6028582B3F3B7600476078 /* ToolbarTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F6028572B3F3B7600476078 /* ToolbarTab.swift */; };
|
||||||
|
@ -63,10 +69,32 @@
|
||||||
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EE29674F7100AFF0BA /* QuickLook.framework */; };
|
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F7335EE29674F7100AFF0BA /* QuickLook.framework */; };
|
||||||
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F12967608F00AFF0BA /* AddRemoteTimelineView.swift */; };
|
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F12967608F00AFF0BA /* AddRemoteTimelineView.swift */; };
|
||||||
9F7335F92968576500AFF0BA /* DisplaySettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7335F82968576500AFF0BA /* DisplaySettingsView.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 */; };
|
9F7D93942980063100EE6B7A /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9F7D93932980063100EE6B7A /* AppAccount */; };
|
||||||
9F7D939A29805DBD00EE6B7A /* AccountSettingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F7D939929805DBD00EE6B7A /* AccountSettingView.swift */; };
|
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 */; };
|
||||||
|
9F9191562C6DDE1F001C89E7 /* WishlistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9191552C6DDE1C001C89E7 /* WishlistView.swift */; };
|
||||||
|
9F9191592C6DDF20001C89E7 /* WishKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9F9191582C6DDF20001C89E7 /* WishKit */; };
|
||||||
9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA6FD6129C04A8800E2312C /* TranslationSettingsView.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 */; };
|
9FAD858B29743F7400496AB1 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD858A29743F7400496AB1 /* ShareViewController.swift */; };
|
||||||
9FAD858E29743F7400496AB1 /* (null) in Resources */ = {isa = PBXBuildFile; };
|
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, ); }; };
|
9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */; platformFilters = (ios, maccatalyst, ); settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
@ -98,6 +126,13 @@
|
||||||
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE3DB56296FEFCA00628CB0 /* AppAccount */; };
|
9FE3DB57296FEFCA00628CB0 /* AppAccount in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE3DB56296FEFCA00628CB0 /* AppAccount */; };
|
||||||
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, maccatalyst, ); productRef = 9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */; };
|
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, maccatalyst, ); productRef = 9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */; };
|
||||||
9FE4CCAD2B4C849F00DA5F13 /* GiphyUISDK in Frameworks */ = {isa = PBXBuildFile; productRef = 9FE4CCAC2B4C849F00DA5F13 /* 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 */; };
|
9FFF677C299B7B2C00FE700A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677B299B7B2C00FE700A /* Notifications */; };
|
||||||
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677F299B7D2B00FE700A /* DesignSystem */; };
|
9FFF6780299B7D2B00FE700A /* DesignSystem in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF677F299B7D2B00FE700A /* DesignSystem */; };
|
||||||
9FFF6782299B7D3A00FE700A /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF6781299B7D3A00FE700A /* Account */; };
|
9FFF6782299B7D3A00FE700A /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9FFF6781299B7D3A00FE700A /* Account */; };
|
||||||
|
@ -123,6 +158,13 @@
|
||||||
remoteGlobalIDString = 9F2A5415296AB631009B2D7C;
|
remoteGlobalIDString = 9F2A5415296AB631009B2D7C;
|
||||||
remoteInfo = IceCubesNotifications;
|
remoteInfo = IceCubesNotifications;
|
||||||
};
|
};
|
||||||
|
9F7788D42BE652B2004E6BEF /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 9FBFE631292A715500C250E9 /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 9F7788C42BE652B1004E6BEF;
|
||||||
|
remoteInfo = IceCubesAppWidgetsExtensionExtension;
|
||||||
|
};
|
||||||
9FAD859029743F7400496AB1 /* PBXContainerItemProxy */ = {
|
9FAD859029743F7400496AB1 /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = 9FBFE631292A715500C250E9 /* Project object */;
|
containerPortal = 9FBFE631292A715500C250E9 /* Project object */;
|
||||||
|
@ -149,6 +191,7 @@
|
||||||
E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */,
|
E9DF420729830FEC0003AAD2 /* IceCubesActionExtension.appex in Embed Foundation Extensions */,
|
||||||
9F2A541D296AB631009B2D7C /* IceCubesNotifications.appex in Embed Foundation Extensions */,
|
9F2A541D296AB631009B2D7C /* IceCubesNotifications.appex in Embed Foundation Extensions */,
|
||||||
9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */,
|
9FAD859229743F7400496AB1 /* IceCubesShareExtension.appex in Embed Foundation Extensions */,
|
||||||
|
9F7788D62BE652B2004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex in Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
name = "Embed Foundation Extensions";
|
name = "Embed Foundation Extensions";
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -197,6 +240,11 @@
|
||||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTab.swift; 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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
9F398AA52935FE8A00A889F2 /* AppRegistry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRegistry.swift; sourceTree = "<group>"; };
|
||||||
|
@ -205,6 +253,9 @@
|
||||||
9F4A48182976B21900A1A038 /* ProfileTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTab.swift; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
9F6028572B3F3B7600476078 /* ToolbarTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToolbarTab.swift; sourceTree = "<group>"; };
|
||||||
|
@ -215,10 +266,25 @@
|
||||||
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
||||||
|
9F9191552C6DDE1C001C89E7 /* WishlistView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WishlistView.swift; sourceTree = "<group>"; };
|
||||||
9FA6FD6129C04A8800E2312C /* TranslationSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TranslationSettingsView.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; };
|
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>"; };
|
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>"; };
|
9FAD858F29743F7400496AB1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
@ -243,6 +309,12 @@
|
||||||
9FE0346A2ADD59AC00529EA8 /* MediaUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = MediaUI; path = Packages/MediaUI; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
C4FBCF6F298FD88A0015DF22 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||||
|
@ -278,6 +350,21 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
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 */ = {
|
9FAD858529743F7400496AB1 /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -300,7 +387,6 @@
|
||||||
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */,
|
9F7335EF29674F7100AFF0BA /* QuickLook.framework in Frameworks */,
|
||||||
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */,
|
9FE4CCAB2B4C848A00DA5F13 /* GiphyUISDK in Frameworks */,
|
||||||
9F7335ED2967463400AFF0BA /* AVKit.framework in Frameworks */,
|
9F7335ED2967463400AFF0BA /* AVKit.framework in Frameworks */,
|
||||||
9F2A540C29699705009B2D7C /* RevenueCat in Frameworks */,
|
|
||||||
9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */,
|
9F2A540E2969A0B0009B2D7C /* StoreKit.framework in Frameworks */,
|
||||||
9F55C6902955993C00F94077 /* Explore in Frameworks */,
|
9F55C6902955993C00F94077 /* Explore in Frameworks */,
|
||||||
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */,
|
9FAE4ACE29379A5A00772766 /* KeychainSwift in Frameworks */,
|
||||||
|
@ -311,8 +397,9 @@
|
||||||
9FD542E72962D2FF0045321A /* Lists in Frameworks */,
|
9FD542E72962D2FF0045321A /* Lists in Frameworks */,
|
||||||
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */,
|
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */,
|
||||||
9F5E581929545BE700A53960 /* Env in Frameworks */,
|
9F5E581929545BE700A53960 /* Env in Frameworks */,
|
||||||
9F2A540A29699705009B2D7C /* ReceiptParser in Frameworks */,
|
|
||||||
DA0B24FB2A6876D50045BDD7 /* SFSafeSymbols in Frameworks */,
|
DA0B24FB2A6876D50045BDD7 /* SFSafeSymbols in Frameworks */,
|
||||||
|
9FE6A42E2BD043A90055D388 /* RevenueCat in Frameworks */,
|
||||||
|
9F9191592C6DDF20001C89E7 /* WishKit in Frameworks */,
|
||||||
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
|
9F295540292B6C3400E0E81B /* Timeline in Frameworks */,
|
||||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */,
|
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */,
|
||||||
9FC2A38B2B49D19A00DFD1C1 /* StatusKit in Frameworks */,
|
9FC2A38B2B49D19A00DFD1C1 /* StatusKit in Frameworks */,
|
||||||
|
@ -351,6 +438,22 @@
|
||||||
path = IceCubesNotifications;
|
path = IceCubesNotifications;
|
||||||
sourceTree = "<group>";
|
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 */ = {
|
9F398AB429360A5800A889F2 /* App */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -375,6 +478,15 @@
|
||||||
path = Resources;
|
path = Resources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
9F5BE6202BF48FB20074387E /* ListsWidget */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9F5BE6212BF48FBA0074387E /* ListsWidget.swift */,
|
||||||
|
9F5BE6232BF48FC40074387E /* ListsWidgetConfiguration.swift */,
|
||||||
|
);
|
||||||
|
path = ListsWidget;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9F654BF0299AC46200D27FA5 /* Report */ = {
|
9F654BF0299AC46200D27FA5 /* Report */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -392,6 +504,33 @@
|
||||||
path = Timeline;
|
path = Timeline;
|
||||||
sourceTree = "<group>";
|
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 */ = {
|
9FA0D2AC29921C1F008A143B /* Embeds */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -456,9 +595,11 @@
|
||||||
DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */,
|
DD31E2E5297FB68B00A4BE29 /* IceCubesApp.xcconfig */,
|
||||||
9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */,
|
9F7D939529800B0300EE6B7A /* IceCubesApp-release.xcconfig */,
|
||||||
9FBFE63B292A715500C250E9 /* IceCubesApp */,
|
9FBFE63B292A715500C250E9 /* IceCubesApp */,
|
||||||
|
9F37BDD92BE36E08007F28AD /* IceCubesAppIntents */,
|
||||||
E9DF41FD29830FEC0003AAD2 /* IceCubesActionExtension */,
|
E9DF41FD29830FEC0003AAD2 /* IceCubesActionExtension */,
|
||||||
9F2A5417296AB631009B2D7C /* IceCubesNotifications */,
|
9F2A5417296AB631009B2D7C /* IceCubesNotifications */,
|
||||||
9FAD858929743F7400496AB1 /* IceCubesShareExtension */,
|
9FAD858929743F7400496AB1 /* IceCubesShareExtension */,
|
||||||
|
9F7788CA2BE652B1004E6BEF /* IceCubesAppWidgetsExtension */,
|
||||||
9FBFE63A292A715500C250E9 /* Products */,
|
9FBFE63A292A715500C250E9 /* Products */,
|
||||||
9FBFE64C292A72BD00C250E9 /* Frameworks */,
|
9FBFE64C292A72BD00C250E9 /* Frameworks */,
|
||||||
9FE3DB55296FEF5800628CB0 /* AppAccount */,
|
9FE3DB55296FEF5800628CB0 /* AppAccount */,
|
||||||
|
@ -484,6 +625,7 @@
|
||||||
9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */,
|
9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */,
|
||||||
9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */,
|
9FAD858829743F7400496AB1 /* IceCubesShareExtension.appex */,
|
||||||
E9DF41FA29830FEC0003AAD2 /* IceCubesActionExtension.appex */,
|
E9DF41FA29830FEC0003AAD2 /* IceCubesActionExtension.appex */,
|
||||||
|
9F7788C52BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -496,7 +638,6 @@
|
||||||
9FAE4AC8293774FF00772766 /* Info.plist */,
|
9FAE4AC8293774FF00772766 /* Info.plist */,
|
||||||
9F398AB429360A5800A889F2 /* App */,
|
9F398AB429360A5800A889F2 /* App */,
|
||||||
9F398AB529360A6100A889F2 /* Resources */,
|
9F398AB529360A6100A889F2 /* Resources */,
|
||||||
9FAD85822971BF7200496AB1 /* Secret.plist */,
|
|
||||||
);
|
);
|
||||||
path = IceCubesApp;
|
path = IceCubesApp;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -509,6 +650,8 @@
|
||||||
9F7335EE29674F7100AFF0BA /* QuickLook.framework */,
|
9F7335EE29674F7100AFF0BA /* QuickLook.framework */,
|
||||||
9F7335EB2967461B00AFF0BA /* AVKit.framework */,
|
9F7335EB2967461B00AFF0BA /* AVKit.framework */,
|
||||||
E9DF41FB29830FEC0003AAD2 /* UniformTypeIdentifiers.framework */,
|
E9DF41FB29830FEC0003AAD2 /* UniformTypeIdentifiers.framework */,
|
||||||
|
9F7788C62BE652B1004E6BEF /* WidgetKit.framework */,
|
||||||
|
9F7788C82BE652B1004E6BEF /* SwiftUI.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -516,6 +659,7 @@
|
||||||
9FE151A4293C90EA00E9683D /* Settings */ = {
|
9FE151A4293C90EA00E9683D /* Settings */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
9F9191552C6DDE1C001C89E7 /* WishlistView.swift */,
|
||||||
069709A9298C9AD7006E4CB5 /* AboutView.swift */,
|
069709A9298C9AD7006E4CB5 /* AboutView.swift */,
|
||||||
9F7D939929805DBD00EE6B7A /* AccountSettingView.swift */,
|
9F7D939929805DBD00EE6B7A /* AccountSettingView.swift */,
|
||||||
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */,
|
9F2B92F9295DA7D700DE16D0 /* AddAccountsView.swift */,
|
||||||
|
@ -538,6 +682,42 @@
|
||||||
path = Settings;
|
path = Settings;
|
||||||
sourceTree = "<group>";
|
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 */ = {
|
E9B576C029743F2A00BCE646 /* Localization */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -589,6 +769,31 @@
|
||||||
productReference = 9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */;
|
productReference = 9F2A5416296AB631009B2D7C /* IceCubesNotifications.appex */;
|
||||||
productType = "com.apple.product-type.app-extension";
|
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 */ = {
|
9FAD858729743F7400496AB1 /* IceCubesShareExtension */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 9FAD859329743F7400496AB1 /* Build configuration list for PBXNativeTarget "IceCubesShareExtension" */;
|
buildConfigurationList = 9FAD859329743F7400496AB1 /* Build configuration list for PBXNativeTarget "IceCubesShareExtension" */;
|
||||||
|
@ -631,6 +836,7 @@
|
||||||
9F2A541C296AB631009B2D7C /* PBXTargetDependency */,
|
9F2A541C296AB631009B2D7C /* PBXTargetDependency */,
|
||||||
9FAD859129743F7400496AB1 /* PBXTargetDependency */,
|
9FAD859129743F7400496AB1 /* PBXTargetDependency */,
|
||||||
E9DF420629830FEC0003AAD2 /* PBXTargetDependency */,
|
E9DF420629830FEC0003AAD2 /* PBXTargetDependency */,
|
||||||
|
9F7788D52BE652B2004E6BEF /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = IceCubesApp;
|
name = IceCubesApp;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
@ -644,12 +850,12 @@
|
||||||
9F55C68F2955993C00F94077 /* Explore */,
|
9F55C68F2955993C00F94077 /* Explore */,
|
||||||
9FD542E62962D2FF0045321A /* Lists */,
|
9FD542E62962D2FF0045321A /* Lists */,
|
||||||
9F7335E92966B3F800AFF0BA /* Conversations */,
|
9F7335E92966B3F800AFF0BA /* Conversations */,
|
||||||
9F2A540929699705009B2D7C /* ReceiptParser */,
|
|
||||||
9F2A540B29699705009B2D7C /* RevenueCat */,
|
|
||||||
9FE3DB56296FEFCA00628CB0 /* AppAccount */,
|
9FE3DB56296FEFCA00628CB0 /* AppAccount */,
|
||||||
DA0B24FA2A6876D50045BDD7 /* SFSafeSymbols */,
|
DA0B24FA2A6876D50045BDD7 /* SFSafeSymbols */,
|
||||||
9FC2A38A2B49D19A00DFD1C1 /* StatusKit */,
|
9FC2A38A2B49D19A00DFD1C1 /* StatusKit */,
|
||||||
9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */,
|
9FE4CCAA2B4C848A00DA5F13 /* GiphyUISDK */,
|
||||||
|
9FE6A42D2BD043A90055D388 /* RevenueCat */,
|
||||||
|
9F9191582C6DDF20001C89E7 /* WishKit */,
|
||||||
);
|
);
|
||||||
productName = IceCubesApp;
|
productName = IceCubesApp;
|
||||||
productReference = 9FBFE639292A715500C250E9 /* Ice Cubes.app */;
|
productReference = 9FBFE639292A715500C250E9 /* Ice Cubes.app */;
|
||||||
|
@ -683,12 +889,15 @@
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
BuildIndependentTargetsInParallel = 1;
|
BuildIndependentTargetsInParallel = 1;
|
||||||
LastSwiftUpdateCheck = 1420;
|
LastSwiftUpdateCheck = 1530;
|
||||||
LastUpgradeCheck = 1500;
|
LastUpgradeCheck = 1600;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
9F2A5415296AB631009B2D7C = {
|
9F2A5415296AB631009B2D7C = {
|
||||||
CreatedOnToolsVersion = 14.2;
|
CreatedOnToolsVersion = 14.2;
|
||||||
};
|
};
|
||||||
|
9F7788C42BE652B1004E6BEF = {
|
||||||
|
CreatedOnToolsVersion = 15.3;
|
||||||
|
};
|
||||||
9FAD858729743F7400496AB1 = {
|
9FAD858729743F7400496AB1 = {
|
||||||
CreatedOnToolsVersion = 14.2;
|
CreatedOnToolsVersion = 14.2;
|
||||||
};
|
};
|
||||||
|
@ -724,13 +933,15 @@
|
||||||
be,
|
be,
|
||||||
uk,
|
uk,
|
||||||
"zh-Hant",
|
"zh-Hant",
|
||||||
|
Base,
|
||||||
);
|
);
|
||||||
mainGroup = 9FBFE630292A715500C250E9;
|
mainGroup = 9FBFE630292A715500C250E9;
|
||||||
packageReferences = (
|
packageReferences = (
|
||||||
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */,
|
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */,
|
||||||
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
|
||||||
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */,
|
||||||
9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */,
|
9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */,
|
||||||
|
9FE6A42C2BD043A80055D388 /* XCRemoteSwiftPackageReference "purchases-ios" */,
|
||||||
|
9F9191572C6DDF20001C89E7 /* XCRemoteSwiftPackageReference "wishkit-ios" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 9FBFE63A292A715500C250E9 /* Products */;
|
productRefGroup = 9FBFE63A292A715500C250E9 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
@ -740,6 +951,7 @@
|
||||||
E9DF41F929830FEC0003AAD2 /* IceCubesActionExtension */,
|
E9DF41F929830FEC0003AAD2 /* IceCubesActionExtension */,
|
||||||
9F2A5415296AB631009B2D7C /* IceCubesNotifications */,
|
9F2A5415296AB631009B2D7C /* IceCubesNotifications */,
|
||||||
9FAD858729743F7400496AB1 /* IceCubesShareExtension */,
|
9FAD858729743F7400496AB1 /* IceCubesShareExtension */,
|
||||||
|
9F7788C42BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
@ -755,6 +967,14 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
9F7788C32BE652B1004E6BEF /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
9F7788D22BE652B2004E6BEF /* Assets.xcassets in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
9FAD858629743F7400496AB1 /* Resources */ = {
|
9FAD858629743F7400496AB1 /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -778,7 +998,6 @@
|
||||||
9F18801829AE477F00D85459 /* favorite.wav in Resources */,
|
9F18801829AE477F00D85459 /* favorite.wav in Resources */,
|
||||||
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */,
|
9F24EEB829360C330042359D /* Preview Assets.xcassets in Resources */,
|
||||||
069709A8298C87B5006E4CB5 /* OpenDyslexic-Regular.otf in Resources */,
|
069709A8298C87B5006E4CB5 /* OpenDyslexic-Regular.otf in Resources */,
|
||||||
9FAD85832971BF7200496AB1 /* Secret.plist in Resources */,
|
|
||||||
9F18801229AE477F00D85459 /* tabSelection.wav in Resources */,
|
9F18801229AE477F00D85459 /* tabSelection.wav in Resources */,
|
||||||
9F18801429AE477F00D85459 /* bookmark.wav in Resources */,
|
9F18801429AE477F00D85459 /* bookmark.wav in Resources */,
|
||||||
9F18801629AE477F00D85459 /* refresh.wav in Resources */,
|
9F18801629AE477F00D85459 /* refresh.wav in Resources */,
|
||||||
|
@ -809,6 +1028,30 @@
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
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 */ = {
|
9FAD858429743F7400496AB1 /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -830,6 +1073,11 @@
|
||||||
9F15D6042B3DC2180008C220 /* NavigationSheet.swift in Sources */,
|
9F15D6042B3DC2180008C220 /* NavigationSheet.swift in Sources */,
|
||||||
9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */,
|
9FA6FD6229C04A8800E2312C /* TranslationSettingsView.swift in Sources */,
|
||||||
9F35DB4C2952005C00B3281A /* MessagesTab.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 */,
|
9FAD85CF2975B68900496AB1 /* SideBarView.swift in Sources */,
|
||||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||||
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */,
|
9FC14EF42B494D940006CEE1 /* RemoteTimelinesSettingView.swift in Sources */,
|
||||||
|
@ -848,9 +1096,13 @@
|
||||||
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */,
|
9F2B92FA295DA7D700DE16D0 /* AddAccountsView.swift in Sources */,
|
||||||
639CDF9C296AC82F00C35E58 /* SafariRouter.swift in Sources */,
|
639CDF9C296AC82F00C35E58 /* SafariRouter.swift in Sources */,
|
||||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */,
|
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */,
|
||||||
|
9F7788ED2BE78D75004E6BEF /* TimelineFilterEntity.swift in Sources */,
|
||||||
|
9F37BDE32BE393A7007F28AD /* AppShortcuts.swift in Sources */,
|
||||||
9F654BEF299AC45B00D27FA5 /* ReportView.swift in Sources */,
|
9F654BEF299AC45B00D27FA5 /* ReportView.swift in Sources */,
|
||||||
|
9F9191562C6DDE1F001C89E7 /* WishlistView.swift in Sources */,
|
||||||
D08A9C3529956CFA00204A4A /* SwipeActionsSettingsView.swift in Sources */,
|
D08A9C3529956CFA00204A4A /* SwipeActionsSettingsView.swift in Sources */,
|
||||||
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */,
|
9F7335F22967608F00AFF0BA /* AddRemoteTimelineView.swift in Sources */,
|
||||||
|
9F7788E82BE65533004E6BEF /* AppAccountEntity.swift in Sources */,
|
||||||
9FC14EF62B494DFF0006CEE1 /* RecenTagsSettingView.swift in Sources */,
|
9FC14EF62B494DFF0006CEE1 /* RecenTagsSettingView.swift in Sources */,
|
||||||
9F6028562B3F36AE00476078 /* AppView.swift in Sources */,
|
9F6028562B3F36AE00476078 /* AppView.swift in Sources */,
|
||||||
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
|
9F55C68D2955968700F94077 /* ExploreTab.swift in Sources */,
|
||||||
|
@ -877,6 +1129,15 @@
|
||||||
target = 9F2A5415296AB631009B2D7C /* IceCubesNotifications */;
|
target = 9F2A5415296AB631009B2D7C /* IceCubesNotifications */;
|
||||||
targetProxy = 9F2A541B296AB631009B2D7C /* PBXContainerItemProxy */;
|
targetProxy = 9F2A541B296AB631009B2D7C /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
|
9F7788D52BE652B2004E6BEF /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
platformFilters = (
|
||||||
|
ios,
|
||||||
|
maccatalyst,
|
||||||
|
);
|
||||||
|
target = 9F7788C42BE652B1004E6BEF /* IceCubesAppWidgetsExtensionExtension */;
|
||||||
|
targetProxy = 9F7788D42BE652B2004E6BEF /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
9FAD859129743F7400496AB1 /* PBXTargetDependency */ = {
|
9FAD859129743F7400496AB1 /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
platformFilters = (
|
platformFilters = (
|
||||||
|
@ -940,7 +1201,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -950,7 +1211,7 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -975,7 +1236,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesNotifications";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -985,12 +1246,84 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
name = Release;
|
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 = 730;
|
||||||
|
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.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.11.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 = 6.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 = 730;
|
||||||
|
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.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.11.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 = 6.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
9FAD859429743F7400496AB1 /* Debug */ = {
|
9FAD859429743F7400496AB1 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -1011,7 +1344,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -1020,7 +1353,7 @@
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -1045,7 +1378,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesShareExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -1054,7 +1387,7 @@
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
|
@ -1123,6 +1456,7 @@
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_STRICT_CONCURRENCY = complete;
|
SWIFT_STRICT_CONCURRENCY = complete;
|
||||||
|
SWIFT_VERSION = "";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1182,17 +1516,18 @@
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_STRICT_CONCURRENCY = complete;
|
SWIFT_STRICT_CONCURRENCY = complete;
|
||||||
|
SWIFT_VERSION = "";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
9FBFE649292A715600C250E9 /* Debug */ = {
|
9FBFE649292A715600C250E9 /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
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 AppIconAlternate9 AppIconAlternate43";
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
|
ASSETCATALOG_COMPILER_STANDALONE_ICON_BEHAVIOR = all;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO;
|
||||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/App/IceCubesApp.entitlements;
|
CODE_SIGN_ENTITLEMENTS = IceCubesApp/App/IceCubesApp.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||||
|
@ -1208,7 +1543,8 @@
|
||||||
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
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_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||||
|
@ -1225,7 +1561,7 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
||||||
PRODUCT_NAME = "Ice Cubes";
|
PRODUCT_NAME = "Ice Cubes";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
|
@ -1234,19 +1570,30 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_STRICT_CONCURRENCY = complete;
|
SWIFT_STRICT_CONCURRENCY = complete;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_UPCOMING_FEATURE_CONCISE_MAGIC_FILE = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_DEPRECATE_APPLICATION_MAIN = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_FORWARD_TRAILING_CLOSURES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_GLOBAL_CONCURRENCY = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_IMPLICIT_OPEN_EXISTENTIALS = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_IMPORT_OBJC_FORWARD_DECLS = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_INFER_SENDABLE_FROM_CAPTURES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_ISOLATED_DEFAULT_VALUES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
||||||
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
|
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
9FBFE64A292A715600C250E9 /* Release */ = {
|
9FBFE64A292A715600C250E9 /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
|
||||||
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 AppIconAlternate9 AppIconAlternate43";
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
|
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||||
|
ASSETCATALOG_COMPILER_STANDALONE_ICON_BEHAVIOR = all;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = NO;
|
||||||
CODE_SIGN_ENTITLEMENTS = "IceCubesApp/App/IceCubesApp-release.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "IceCubesApp/App/IceCubesApp-release.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "-";
|
CODE_SIGN_IDENTITY = "-";
|
||||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
|
||||||
|
@ -1262,7 +1609,8 @@
|
||||||
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
INFOPLIST_FILE = IceCubesApp/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
INFOPLIST_KEY_CFBundleDisplayName = "Ice Cubes";
|
||||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
|
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_NSPhotoLibraryUsageDescription = "Upload photos & videos to Mastodon";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
|
||||||
|
@ -1279,7 +1627,7 @@
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
|
||||||
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
MACOSX_DEPLOYMENT_TARGET = 13.0;
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp";
|
||||||
PRODUCT_NAME = "Ice Cubes";
|
PRODUCT_NAME = "Ice Cubes";
|
||||||
SDKROOT = auto;
|
SDKROOT = auto;
|
||||||
|
@ -1288,8 +1636,19 @@
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_STRICT_CONCURRENCY = complete;
|
SWIFT_STRICT_CONCURRENCY = complete;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_UPCOMING_FEATURE_CONCISE_MAGIC_FILE = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_DEPRECATE_APPLICATION_MAIN = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_DISABLE_OUTWARD_ACTOR_ISOLATION = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_FORWARD_TRAILING_CLOSURES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_GLOBAL_CONCURRENCY = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_IMPLICIT_OPEN_EXISTENTIALS = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_IMPORT_OBJC_FORWARD_DECLS = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_INFER_SENDABLE_FROM_CAPTURES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_ISOLATED_DEFAULT_VALUES = YES;
|
||||||
|
SWIFT_UPCOMING_FEATURE_REGION_BASED_ISOLATION = YES;
|
||||||
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2,7";
|
TARGETED_DEVICE_FAMILY = "1,2,7";
|
||||||
|
_EXPERIMENTAL_SWIFT_EXPLICIT_MODULES = NO;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -1314,7 +1673,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -1323,7 +1682,7 @@
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -1349,7 +1708,7 @@
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.10.22;
|
MARKETING_VERSION = 1.11.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
PRODUCT_BUNDLE_IDENTIFIER = "$(BUNDLE_ID_PREFIX).IceCubesApp.IceCubesActionExtension";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
|
@ -1358,7 +1717,7 @@
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 6.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
|
@ -1376,6 +1735,15 @@
|
||||||
defaultConfigurationIsVisible = 0;
|
defaultConfigurationIsVisible = 0;
|
||||||
defaultConfigurationName = Release;
|
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" */ = {
|
9FAD859329743F7400496AB1 /* Build configuration list for PBXNativeTarget "IceCubesShareExtension" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
@ -1415,12 +1783,12 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCRemoteSwiftPackageReference section */
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
9F2A540829699705009B2D7C /* XCRemoteSwiftPackageReference "purchases-ios" */ = {
|
9F9191572C6DDF20001C89E7 /* XCRemoteSwiftPackageReference "wishkit-ios" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/RevenueCat/purchases-ios.git";
|
repositoryURL = "https://github.com/wishkit/wishkit-ios.git";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = upToNextMajorVersion;
|
kind = upToNextMajorVersion;
|
||||||
minimumVersion = 4.0.0;
|
minimumVersion = 4.1.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */ = {
|
9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */ = {
|
||||||
|
@ -1436,7 +1804,15 @@
|
||||||
repositoryURL = "https://github.com/Giphy/giphy-ios-sdk";
|
repositoryURL = "https://github.com/Giphy/giphy-ios-sdk";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = upToNextMajorVersion;
|
kind = upToNextMajorVersion;
|
||||||
minimumVersion = 2.2.7;
|
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" */ = {
|
DA0B24F92A6876D40045BDD7 /* XCRemoteSwiftPackageReference "SFSafeSymbols" */ = {
|
||||||
|
@ -1454,16 +1830,6 @@
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Timeline;
|
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 */ = {
|
9F2A5423296AB67A009B2D7C /* Env */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Env;
|
productName = Env;
|
||||||
|
@ -1501,10 +1867,39 @@
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Conversations;
|
productName = Conversations;
|
||||||
};
|
};
|
||||||
|
9F7788DD2BE6543D004E6BEF /* Account */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Account;
|
||||||
|
};
|
||||||
|
9F7788DF2BE6543D004E6BEF /* AppAccount */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = AppAccount;
|
||||||
|
};
|
||||||
|
9F7788E12BE6543D004E6BEF /* Env */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Env;
|
||||||
|
};
|
||||||
|
9F7788E32BE6543D004E6BEF /* Models */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Models;
|
||||||
|
};
|
||||||
|
9F7788E52BE6543D004E6BEF /* Network */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Network;
|
||||||
|
};
|
||||||
|
9F7788EF2BE78E77004E6BEF /* Timeline */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = Timeline;
|
||||||
|
};
|
||||||
9F7D93932980063100EE6B7A /* AppAccount */ = {
|
9F7D93932980063100EE6B7A /* AppAccount */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = AppAccount;
|
productName = AppAccount;
|
||||||
};
|
};
|
||||||
|
9F9191582C6DDF20001C89E7 /* WishKit */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 9F9191572C6DDF20001C89E7 /* XCRemoteSwiftPackageReference "wishkit-ios" */;
|
||||||
|
productName = WishKit;
|
||||||
|
};
|
||||||
9FAD8599297440CB00496AB1 /* KeychainSwift */ = {
|
9FAD8599297440CB00496AB1 /* KeychainSwift */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */;
|
package = 9FAE4ACC29379A5A00772766 /* XCRemoteSwiftPackageReference "keychain-swift" */;
|
||||||
|
@ -1569,6 +1964,11 @@
|
||||||
package = 9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
package = 9FE4CCA92B4C848A00DA5F13 /* XCRemoteSwiftPackageReference "giphy-ios-sdk" */;
|
||||||
productName = GiphyUISDK;
|
productName = GiphyUISDK;
|
||||||
};
|
};
|
||||||
|
9FE6A42D2BD043A90055D388 /* RevenueCat */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 9FE6A42C2BD043A80055D388 /* XCRemoteSwiftPackageReference "purchases-ios" */;
|
||||||
|
productName = RevenueCat;
|
||||||
|
};
|
||||||
9FFF677B299B7B2C00FE700A /* Notifications */ = {
|
9FFF677B299B7B2C00FE700A /* Notifications */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = Notifications;
|
productName = Notifications;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
{
|
{
|
||||||
|
"originHash" : "b7af8c2ab18771d4cebfbeb66d91559df500516a12027cd67834b2a576eb3df0",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "bodega",
|
"identity" : "bodega",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/mergesort/Bodega",
|
"location" : "https://github.com/mergesort/Bodega",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "f0554077c178088ba11557bbdbb71775cc6a1b84",
|
"revision" : "bfd8871e9c2590d31b200e54c75428a71483afdf",
|
||||||
"version" : "2.1.0"
|
"version" : "2.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -14,8 +15,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/Dean151/ButtonKit",
|
"location" : "https://github.com/Dean151/ButtonKit",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "377f5bab4ed047704316d531e0826d4de5ebf6a4",
|
"revision" : "d567519b297777c38dee56ef10201fef4962ff75",
|
||||||
"version" : "0.1.1"
|
"version" : "0.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -23,8 +24,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/divadretlaw/EmojiText",
|
"location" : "https://github.com/divadretlaw/EmojiText",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "d0664390e3236ff6241ea0586d80f4e92702973b",
|
"revision" : "174a7bc7bd75650ad1acb5679dbb754296093de0",
|
||||||
"version" : "3.2.1"
|
"version" : "4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -32,8 +33,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/Giphy/giphy-ios-sdk",
|
"location" : "https://github.com/Giphy/giphy-ios-sdk",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "95c32b862185e76107841b49bfff8ff7230f3b68",
|
"revision" : "fb61ec12738133eb3b9bf62ed11d1bf93d9b4b20",
|
||||||
"version" : "2.2.7"
|
"version" : "2.2.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -42,7 +43,7 @@
|
||||||
"location" : "https://github.com/evgenyneu/keychain-swift",
|
"location" : "https://github.com/evgenyneu/keychain-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"branch" : "master",
|
"branch" : "master",
|
||||||
"revision" : "f38cb0ada97847ac5068b915b8d2793b35435668"
|
"revision" : "5e1b02b6a9dac2a759a1d5dbc175c86bd192a608"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -59,8 +60,8 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/nicklockwood/LRUCache",
|
"location" : "https://github.com/nicklockwood/LRUCache",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "6d2b5246c9c98dcd498552bb22f08d55b12a8371",
|
"revision" : "542f0449556327415409ededc9c43a4bd0a397dc",
|
||||||
"version" : "1.0.4"
|
"version" : "1.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -68,17 +69,17 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/kean/Nuke",
|
"location" : "https://github.com/kean/Nuke",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "1694798e876113d44f6ec6ead965d7286695981d",
|
"revision" : "0ead44350d2737db384908569c012fe67c421e4d",
|
||||||
"version" : "12.2.0"
|
"version" : "12.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "purchases-ios",
|
"identity" : "purchases-ios",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/RevenueCat/purchases-ios.git",
|
"location" : "https://github.com/RevenueCat/purchases-ios",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "b8d20ba1c8e13cc73d72e37cf98607d01fd357b6",
|
"revision" : "7d55b964114a3d4a76791227cdc28577617596db",
|
||||||
"version" : "4.31.2"
|
"version" : "4.43.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -95,8 +96,35 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/stephencelis/SQLite.swift.git",
|
"location" : "https://github.com/stephencelis/SQLite.swift.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb",
|
"revision" : "a95fc6df17d108bd99210db5e8a9bac90fe984b8",
|
||||||
"version" : "0.14.1"
|
"version" : "0.15.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-cmark",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-cmark.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "3ccff77b2dc5b96b77db3da0d68d28068593fa53",
|
||||||
|
"version" : "0.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-markdown",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/apple/swift-markdown",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "8f79cb175981458a0a27e76cb42fee8e17b1a993",
|
||||||
|
"version" : "0.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swiftsdk",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/TelemetryDeck/SwiftSDK",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "13a26cf125b70d695913eb9bea9f9b9c29da5790",
|
||||||
|
"version" : "2.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -104,28 +132,46 @@
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/scinfu/SwiftSoup.git",
|
"location" : "https://github.com/scinfu/SwiftSoup.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "8b6cf29eead8841a1fa7822481cb3af4ddaadba6",
|
"revision" : "3c2c7e1e72b8abd96eafbae80323c5c1e5317437",
|
||||||
"version" : "2.6.1"
|
"version" : "2.7.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swiftui-introspect",
|
"identity" : "swiftui-introspect",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/siteline/SwiftUI-Introspect.git",
|
"location" : "https://github.com/siteline/swiftui-introspect",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9e1cc02a65b22e09a8251261cccbccce02731fc5",
|
"revision" : "668a65735751432b640260c56dfa621cec568368",
|
||||||
"version" : "1.1.1"
|
"version" : "1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swiftui-shimmer",
|
"identity" : "wishkit-ios",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/markiv/SwiftUI-Shimmer",
|
"location" : "https://github.com/wishkit/wishkit-ios.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "965a7cbcbf094cbcf22b9251a2323bdc3432e171",
|
"revision" : "2b5eb8d1fb13706f8c14767a5239e34e403375f1",
|
||||||
"version" : "1.1.0"
|
"version" : "4.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "wishkit-ios-shared",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/wishkit/wishkit-ios-shared.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "118c9c482e4ad57c65d664283516425b98616483",
|
||||||
|
"version" : "1.4.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "wrappinghstack",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/dkk/WrappingHStack",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "425d9488ba55f58f0b34498c64c054c77fc2a44b",
|
||||||
|
"version" : "2.2.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 2
|
"version" : 3
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1500"
|
LastUpgradeVersion = "1600"
|
||||||
wasCreatedForAppExtension = "YES"
|
wasCreatedForAppExtension = "YES"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1500"
|
LastUpgradeVersion = "1600"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1600"
|
||||||
|
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>
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1500"
|
LastUpgradeVersion = "1600"
|
||||||
wasCreatedForAppExtension = "YES"
|
wasCreatedForAppExtension = "YES"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
|
@ -56,8 +56,12 @@
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
allowLocationSimulation = "YES"
|
allowLocationSimulation = "YES"
|
||||||
launchAutomaticallySubstyle = "2">
|
launchAutomaticallySubstyle = "2">
|
||||||
<BuildableProductRunnable
|
<RemoteRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "1"
|
||||||
|
BundleIdentifier = "com.thomasricouard.IceCubesApp"
|
||||||
|
RemotePath = "/Users/dimillian/Library/Developer/CoreSimulator/Devices/8EF923D0-4CF1-49B6-B287-5F05AD5440C1/data/Containers/Bundle/Application/C447A1D1-9BC9-49C9-8FA5-130E8403972F/Ice Cubes.app">
|
||||||
|
</RemoteRunnable>
|
||||||
|
<MacroExpansion>
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "9FBFE638292A715500C250E9"
|
BlueprintIdentifier = "9FBFE638292A715500C250E9"
|
||||||
|
@ -65,7 +69,7 @@
|
||||||
BlueprintName = "IceCubesApp"
|
BlueprintName = "IceCubesApp"
|
||||||
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
ReferencedContainer = "container:IceCubesApp.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</MacroExpansion>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
buildConfiguration = "Release"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1500"
|
LastUpgradeVersion = "1600"
|
||||||
wasCreatedForAppExtension = "YES"
|
wasCreatedForAppExtension = "YES"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
|
|
|
@ -8,6 +8,7 @@ import LinkPresentation
|
||||||
import Lists
|
import Lists
|
||||||
import MediaUI
|
import MediaUI
|
||||||
import Models
|
import Models
|
||||||
|
import Notifications
|
||||||
import StatusKit
|
import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Timeline
|
import Timeline
|
||||||
|
@ -18,11 +19,13 @@ extension View {
|
||||||
navigationDestination(for: RouterDestination.self) { destination in
|
navigationDestination(for: RouterDestination.self) { destination in
|
||||||
switch destination {
|
switch destination {
|
||||||
case let .accountDetail(id):
|
case let .accountDetail(id):
|
||||||
AccountDetailView(accountId: id, scrollToTopSignal: .constant(0))
|
AccountDetailView(accountId: id)
|
||||||
case let .accountDetailWithAccount(account):
|
case let .accountDetailWithAccount(account):
|
||||||
AccountDetailView(account: account, scrollToTopSignal: .constant(0))
|
AccountDetailView(account: account)
|
||||||
case let .accountSettingsWithAccount(account, appAccount):
|
case let .accountSettingsWithAccount(account, appAccount):
|
||||||
AccountSettingsView(account: account, appAccount: appAccount)
|
AccountSettingsView(account: account, appAccount: appAccount)
|
||||||
|
case let .accountMediaGridView(account, initialMedia):
|
||||||
|
AccountDetailMediaGridView(account: account, initialMediaStatuses: initialMedia)
|
||||||
case let .statusDetail(id):
|
case let .statusDetail(id):
|
||||||
StatusDetailView(statusId: id)
|
StatusDetailView(statusId: id)
|
||||||
case let .statusDetailWithStatus(status):
|
case let .statusDetailWithStatus(status):
|
||||||
|
@ -35,13 +38,16 @@ extension View {
|
||||||
TimelineView(timeline: .constant(.hashtag(tag: tag, accountId: accountId)),
|
TimelineView(timeline: .constant(.hashtag(tag: tag, accountId: accountId)),
|
||||||
pinnedFilters: .constant([]),
|
pinnedFilters: .constant([]),
|
||||||
selectedTagGroup: .constant(nil),
|
selectedTagGroup: .constant(nil),
|
||||||
scrollToTopSignal: .constant(0),
|
|
||||||
canFilterTimeline: false)
|
canFilterTimeline: false)
|
||||||
case let .list(list):
|
case let .list(list):
|
||||||
TimelineView(timeline: .constant(.list(list: list)),
|
TimelineView(timeline: .constant(.list(list: list)),
|
||||||
pinnedFilters: .constant([]),
|
pinnedFilters: .constant([]),
|
||||||
selectedTagGroup: .constant(nil),
|
selectedTagGroup: .constant(nil),
|
||||||
scrollToTopSignal: .constant(0),
|
canFilterTimeline: false)
|
||||||
|
case let .linkTimeline(url, title):
|
||||||
|
TimelineView(timeline: .constant(.link(url: url, title: title)),
|
||||||
|
pinnedFilters: .constant([]),
|
||||||
|
selectedTagGroup: .constant(nil),
|
||||||
canFilterTimeline: false)
|
canFilterTimeline: false)
|
||||||
case let .following(id):
|
case let .following(id):
|
||||||
AccountsListView(mode: .following(accountId: id))
|
AccountsListView(mode: .following(accountId: id))
|
||||||
|
@ -57,12 +63,20 @@ extension View {
|
||||||
TimelineView(timeline: .constant(.trending),
|
TimelineView(timeline: .constant(.trending),
|
||||||
pinnedFilters: .constant([]),
|
pinnedFilters: .constant([]),
|
||||||
selectedTagGroup: .constant(nil),
|
selectedTagGroup: .constant(nil),
|
||||||
scrollToTopSignal: .constant(0),
|
|
||||||
canFilterTimeline: false)
|
canFilterTimeline: false)
|
||||||
case let .trendingLinks(cards):
|
case let .trendingLinks(cards):
|
||||||
CardsListView(cards: cards)
|
TrendingLinksListView(cards: cards)
|
||||||
case let .tagsList(tags):
|
case let .tagsList(tags):
|
||||||
TagsListView(tags: tags)
|
TagsListView(tags: tags)
|
||||||
|
case .notificationsRequests:
|
||||||
|
NotificationsRequestsListView()
|
||||||
|
case let .notificationForAccount(accountId):
|
||||||
|
NotificationsListView(lockedType: nil,
|
||||||
|
lockedAccountId: accountId)
|
||||||
|
case .blockedAccounts:
|
||||||
|
AccountsListView(mode: .blocked)
|
||||||
|
case .mutedAccounts:
|
||||||
|
AccountsListView(mode: .muted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +88,13 @@ extension View {
|
||||||
StatusEditor.MainView(mode: .replyTo(status: status))
|
StatusEditor.MainView(mode: .replyTo(status: status))
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
case let .newStatusEditor(visibility):
|
case let .newStatusEditor(visibility):
|
||||||
StatusEditor.MainView(mode: .new(visibility: 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()
|
.withEnvironments()
|
||||||
case let .editStatusEditor(status):
|
case let .editStatusEditor(status):
|
||||||
StatusEditor.MainView(mode: .edit(status: status))
|
StatusEditor.MainView(mode: .edit(status: status))
|
||||||
|
@ -82,6 +102,9 @@ extension View {
|
||||||
case let .quoteStatusEditor(status):
|
case let .quoteStatusEditor(status):
|
||||||
StatusEditor.MainView(mode: .quote(status: status))
|
StatusEditor.MainView(mode: .quote(status: status))
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
|
case let .quoteLinkStatusEditor(link):
|
||||||
|
StatusEditor.MainView(mode: .quoteLink(link: link))
|
||||||
|
.withEnvironments()
|
||||||
case let .mentionStatusEditor(account, visibility):
|
case let .mentionStatusEditor(account, visibility):
|
||||||
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
|
@ -107,7 +130,7 @@ extension View {
|
||||||
StatusEditHistoryView(statusId: status)
|
StatusEditHistoryView(statusId: status)
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
case .settings:
|
case .settings:
|
||||||
SettingsTabs(popToRootTab: .constant(.settings), isModal: true)
|
SettingsTabs(isModal: true)
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
|
||||||
case .accountPushNotficationsSettings:
|
case .accountPushNotficationsSettings:
|
||||||
|
@ -135,6 +158,13 @@ extension View {
|
||||||
case .timelineContentFilter:
|
case .timelineContentFilter:
|
||||||
NavigationSheet { TimelineContentFilterView() }
|
NavigationSheet { TimelineContentFilterView() }
|
||||||
.presentationDetents([.medium])
|
.presentationDetents([.medium])
|
||||||
|
.presentationBackground(.thinMaterial)
|
||||||
|
.withEnvironments()
|
||||||
|
case .accountEditInfo:
|
||||||
|
EditAccountView()
|
||||||
|
.withEnvironments()
|
||||||
|
case .accountFiltersList:
|
||||||
|
FiltersListView()
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +231,7 @@ struct ActivityView: UIViewControllerRepresentable {
|
||||||
func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext<ActivityView>) {}
|
func updateUIViewController(_: UIActivityViewController, context _: UIViewControllerRepresentableContext<ActivityView>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension URL: Identifiable {
|
extension URL: @retroactive Identifiable {
|
||||||
public var id: String {
|
public var id: String {
|
||||||
absoluteString
|
absoluteString
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,63 +18,49 @@ struct AppView: View {
|
||||||
@Environment(Theme.self) private var theme
|
@Environment(Theme.self) private var theme
|
||||||
@Environment(StreamWatcher.self) private var watcher
|
@Environment(StreamWatcher.self) private var watcher
|
||||||
|
|
||||||
|
@Environment(\.openWindow) var openWindow
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
|
|
||||||
|
@Binding var selectedTab: AppTab
|
||||||
@Binding var selectedTab: Tab
|
|
||||||
@Binding var appRouterPath: RouterPath
|
@Binding var appRouterPath: RouterPath
|
||||||
|
|
||||||
@State var popToRootTab: Tab = .other
|
|
||||||
@State var iosTabs = iOSTabs.shared
|
@State var iosTabs = iOSTabs.shared
|
||||||
@State var sidebarTabs = SidebarTabs.shared
|
@State var sidebarTabs = SidebarTabs.shared
|
||||||
|
@State var selectedTabScrollToTop: Int = -1
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
tabBarView
|
|
||||||
#else
|
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
|
||||||
sidebarView
|
|
||||||
} else {
|
|
||||||
tabBarView
|
tabBarView
|
||||||
}
|
#else
|
||||||
|
if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac {
|
||||||
|
sidebarView
|
||||||
|
} else {
|
||||||
|
tabBarView
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var availableTabs: [Tab] {
|
var availableTabs: [AppTab] {
|
||||||
guard appAccountsManager.currentClient.isAuth else {
|
guard appAccountsManager.currentClient.isAuth else {
|
||||||
return Tab.loggedOutTab()
|
return AppTab.loggedOutTab()
|
||||||
}
|
}
|
||||||
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
if UIDevice.current.userInterfaceIdiom == .phone || horizontalSizeClass == .compact {
|
||||||
return iosTabs.tabs
|
return iosTabs.tabs
|
||||||
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
} else if UIDevice.current.userInterfaceIdiom == .vision {
|
||||||
return Tab.visionOSTab()
|
return AppTab.visionOSTab()
|
||||||
}
|
}
|
||||||
return sidebarTabs.tabs.map{ $0.tab }
|
return sidebarTabs.tabs.map { $0.tab }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
var tabBarView: some View {
|
var tabBarView: some View {
|
||||||
TabView(selection: .init(get: {
|
TabView(selection: .init(get: {
|
||||||
selectedTab
|
selectedTab
|
||||||
}, set: { newTab in
|
}, set: { newTab in
|
||||||
if newTab == .post {
|
updateTab(with: newTab)
|
||||||
appRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if newTab == selectedTab {
|
|
||||||
/// Stupid hack to trigger onChange binding in tab views.
|
|
||||||
popToRootTab = .other
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
|
||||||
popToRootTab = selectedTab
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HapticManager.shared.fireHaptic(.tabSelection)
|
|
||||||
SoundEffectManager.shared.playSound(.tabSelection)
|
|
||||||
|
|
||||||
selectedTab = newTab
|
|
||||||
})) {
|
})) {
|
||||||
ForEach(availableTabs) { tab in
|
ForEach(availableTabs) { tab in
|
||||||
tab.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
tab.makeContentView(selectedTab: $selectedTab)
|
||||||
.tabItem {
|
.tabItem {
|
||||||
if userPreferences.showiPhoneTabLabel {
|
if userPreferences.showiPhoneTabLabel {
|
||||||
tab.label
|
tab.label
|
||||||
|
@ -85,14 +71,40 @@ struct AppView: View {
|
||||||
}
|
}
|
||||||
.tag(tab)
|
.tag(tab)
|
||||||
.badge(badgeFor(tab: 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)
|
.id(appAccountsManager.currentClient.id)
|
||||||
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
||||||
|
.environment(\.selectedTabScrollToTop, selectedTabScrollToTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func updateTab(with newTab: AppTab) {
|
||||||
|
if newTab == .post {
|
||||||
|
#if os(visionOS)
|
||||||
|
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
||||||
|
#else
|
||||||
|
appRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
||||||
|
#endif
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
HapticManager.shared.fireHaptic(.tabSelection)
|
||||||
|
SoundEffectManager.shared.playSound(.tabSelection)
|
||||||
|
|
||||||
|
if selectedTab == newTab {
|
||||||
|
selectedTabScrollToTop = newTab.rawValue
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
||||||
|
selectedTabScrollToTop = -1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedTabScrollToTop = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedTab = newTab
|
||||||
|
}
|
||||||
|
|
||||||
|
private func badgeFor(tab: AppTab) -> Int {
|
||||||
if tab == .notifications, selectedTab != tab,
|
if tab == .notifications, selectedTab != tab,
|
||||||
let token = appAccountsManager.currentAccount.oauthToken
|
let token = appAccountsManager.currentAccount.oauthToken
|
||||||
{
|
{
|
||||||
|
@ -102,43 +114,65 @@ struct AppView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
var sidebarView: some View {
|
var sidebarView: some View {
|
||||||
SideBarView(selectedTab: $selectedTab,
|
SideBarView(selectedTab: .init(get: {
|
||||||
popToRootTab: $popToRootTab,
|
selectedTab
|
||||||
tabs: availableTabs)
|
}, set: { newTab in
|
||||||
{
|
updateTab(with: newTab)
|
||||||
HStack(spacing: 0) {
|
}), tabs: availableTabs)
|
||||||
TabView(selection: $selectedTab) {
|
{
|
||||||
ForEach(availableTabs) { tab in
|
HStack(spacing: 0) {
|
||||||
tab
|
if #available(iOS 18.0, *) {
|
||||||
.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
baseTabView
|
||||||
.tabItem {
|
#if targetEnvironment(macCatalyst)
|
||||||
tab.label
|
.tabViewStyle(.sidebarAdaptable)
|
||||||
}
|
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
||||||
.tag(tab)
|
tabview.sidebar.isHidden = true
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
.tabViewStyle(.tabBarOnly)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
baseTabView
|
||||||
|
}
|
||||||
|
if horizontalSizeClass == .regular,
|
||||||
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.environment(appRouterPath)
|
||||||
|
.environment(\.selectedTabScrollToTop, selectedTabScrollToTop)
|
||||||
}
|
}
|
||||||
.environment(appRouterPath)
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private var baseTabView: some View {
|
||||||
|
TabView(selection: $selectedTab) {
|
||||||
|
ForEach(availableTabs) { tab in
|
||||||
|
tab
|
||||||
|
.makeContentView(selectedTab: $selectedTab)
|
||||||
|
.toolbar(horizontalSizeClass == .regular ? .hidden : .visible, for: .tabBar)
|
||||||
|
.tabItem {
|
||||||
|
tab.label
|
||||||
|
}
|
||||||
|
.tag(tab)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
||||||
|
tabview.tabBar.isHidden = horizontalSizeClass == .regular
|
||||||
|
tabview.customizableViewControllers = []
|
||||||
|
tabview.moreNavigationController.isNavigationBarHidden = true
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
var notificationsSecondaryColumn: some View {
|
var notificationsSecondaryColumn: some View {
|
||||||
NotificationsTab(selectedTab: .constant(.notifications),
|
NotificationsTab(selectedTab: .constant(.notifications)
|
||||||
popToRootTab: $popToRootTab, lockedType: nil)
|
, lockedType: nil)
|
||||||
.environment(\.isSecondaryColumn, true)
|
.environment(\.isSecondaryColumn, true)
|
||||||
.frame(maxWidth: .secondaryColumnWidth)
|
.frame(maxWidth: .secondaryColumnWidth)
|
||||||
.id(appAccountsManager.currentAccount.id)
|
.id(appAccountsManager.currentAccount.id)
|
||||||
|
|
|
@ -4,6 +4,12 @@ import SwiftUI
|
||||||
extension IceCubesApp {
|
extension IceCubesApp {
|
||||||
@CommandsBuilder
|
@CommandsBuilder
|
||||||
var appMenu: some Commands {
|
var appMenu: some Commands {
|
||||||
|
CommandGroup(replacing: .appSettings) {
|
||||||
|
Button("menu.settings") {
|
||||||
|
appRouterPath.presentedSheet = .settings
|
||||||
|
}
|
||||||
|
.keyboardShortcut(",", modifiers: .command)
|
||||||
|
}
|
||||||
CommandGroup(replacing: .newItem) {
|
CommandGroup(replacing: .newItem) {
|
||||||
Button("menu.new-window") {
|
Button("menu.new-window") {
|
||||||
openWindow(id: "MainWindow")
|
openWindow(id: "MainWindow")
|
||||||
|
@ -54,5 +60,11 @@ extension IceCubesApp {
|
||||||
}
|
}
|
||||||
.keyboardShortcut("l", modifiers: .shift)
|
.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,3 +1,4 @@
|
||||||
|
import AppIntents
|
||||||
import Env
|
import Env
|
||||||
import MediaUI
|
import MediaUI
|
||||||
import StatusKit
|
import StatusKit
|
||||||
|
@ -22,13 +23,23 @@ extension IceCubesApp {
|
||||||
.environment(theme)
|
.environment(theme)
|
||||||
.environment(watcher)
|
.environment(watcher)
|
||||||
.environment(pushNotificationsService)
|
.environment(pushNotificationsService)
|
||||||
|
.environment(appIntentService)
|
||||||
.environment(\.isSupporter, isSupporter)
|
.environment(\.isSupporter, isSupporter)
|
||||||
.sheet(item: $quickLook.selectedMediaAttachment) { selectedMediaAttachment in
|
.sheet(item: $quickLook.selectedMediaAttachment) { selectedMediaAttachment in
|
||||||
MediaUIView(selectedAttachment: selectedMediaAttachment,
|
if #available(iOS 18.0, *) {
|
||||||
attachments: quickLook.mediaAttachments)
|
MediaUIView(selectedAttachment: selectedMediaAttachment,
|
||||||
|
attachments: quickLook.mediaAttachments)
|
||||||
|
.presentationBackground(.ultraThinMaterial)
|
||||||
|
.presentationCornerRadius(16)
|
||||||
|
.presentationSizing(.page)
|
||||||
|
.withEnvironments()
|
||||||
|
} else {
|
||||||
|
MediaUIView(selectedAttachment: selectedMediaAttachment,
|
||||||
|
attachments: quickLook.mediaAttachments)
|
||||||
.presentationBackground(.ultraThinMaterial)
|
.presentationBackground(.ultraThinMaterial)
|
||||||
.presentationCornerRadius(16)
|
.presentationCornerRadius(16)
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
|
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
|
||||||
if newValue != nil {
|
if newValue != nil {
|
||||||
|
@ -47,13 +58,14 @@ extension IceCubesApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onChange(of: appIntentService.handledIntent) { _, _ in
|
||||||
|
if let intent = appIntentService.handledIntent?.intent {
|
||||||
|
handleIntent(intent)
|
||||||
|
appIntentService.handledIntent = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
.withModelContainer()
|
.withModelContainer()
|
||||||
}
|
}
|
||||||
#if targetEnvironment(macCatalyst)
|
|
||||||
.defaultSize(width: userPreferences.showiPadSecondaryColumn ? 1100 : 800, height: 1400)
|
|
||||||
#elseif os(visionOS)
|
|
||||||
.defaultSize(width: 800, height: 1200)
|
|
||||||
#endif
|
|
||||||
.commands {
|
.commands {
|
||||||
appMenu
|
appMenu
|
||||||
}
|
}
|
||||||
|
@ -66,6 +78,11 @@ extension IceCubesApp {
|
||||||
watcher.watch(streams: [.user, .direct])
|
watcher.watch(streams: [.user, .direct])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if targetEnvironment(macCatalyst)
|
||||||
|
.windowResize()
|
||||||
|
#elseif os(visionOS)
|
||||||
|
.defaultSize(width: 800, height: 1200)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@SceneBuilder
|
@SceneBuilder
|
||||||
|
@ -74,7 +91,9 @@ extension IceCubesApp {
|
||||||
Group {
|
Group {
|
||||||
switch destination.wrappedValue {
|
switch destination.wrappedValue {
|
||||||
case let .newStatusEditor(visibility):
|
case let .newStatusEditor(visibility):
|
||||||
StatusEditor.MainView(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):
|
case let .editStatusEditor(status):
|
||||||
StatusEditor.MainView(mode: .edit(status: status))
|
StatusEditor.MainView(mode: .edit(status: status))
|
||||||
case let .quoteStatusEditor(status):
|
case let .quoteStatusEditor(status):
|
||||||
|
@ -83,11 +102,15 @@ extension IceCubesApp {
|
||||||
StatusEditor.MainView(mode: .replyTo(status: status))
|
StatusEditor.MainView(mode: .replyTo(status: status))
|
||||||
case let .mentionStatusEditor(account, visibility):
|
case let .mentionStatusEditor(account, visibility):
|
||||||
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
StatusEditor.MainView(mode: .mention(account: account, visibility: visibility))
|
||||||
|
case let .quoteLinkStatusEditor(link):
|
||||||
|
StatusEditor.MainView(mode: .quoteLink(link: link))
|
||||||
case .none:
|
case .none:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
|
.environment(\.isCatalystWindow, true)
|
||||||
|
.environment(RouterPath())
|
||||||
.withModelContainer()
|
.withModelContainer()
|
||||||
.applyTheme(theme)
|
.applyTheme(theme)
|
||||||
.frame(minWidth: 300, minHeight: 400)
|
.frame(minWidth: 300, minHeight: 400)
|
||||||
|
@ -108,9 +131,39 @@ extension IceCubesApp {
|
||||||
.withEnvironments()
|
.withEnvironments()
|
||||||
.withModelContainer()
|
.withModelContainer()
|
||||||
.applyTheme(theme)
|
.applyTheme(theme)
|
||||||
|
.environment(\.isCatalystWindow, true)
|
||||||
.frame(minWidth: 300, minHeight: 400)
|
.frame(minWidth: 300, minHeight: 400)
|
||||||
}
|
}
|
||||||
.defaultSize(width: 1200, height: 1000)
|
.defaultSize(width: 1200, height: 1000)
|
||||||
.windowResizability(.contentMinSize)
|
.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Scene {
|
||||||
|
func windowResize() -> some Scene {
|
||||||
|
if #available(iOS 18.0, *) {
|
||||||
|
return self.windowResizability(.contentSize)
|
||||||
|
} else {
|
||||||
|
return self.defaultSize(width: 1100, height: 1400)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import RevenueCat
|
||||||
import StatusKit
|
import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Timeline
|
import Timeline
|
||||||
|
import WishKit
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct IceCubesApp: App {
|
struct IceCubesApp: App {
|
||||||
|
@ -23,11 +24,12 @@ struct IceCubesApp: App {
|
||||||
@State var currentAccount = CurrentAccount.shared
|
@State var currentAccount = CurrentAccount.shared
|
||||||
@State var userPreferences = UserPreferences.shared
|
@State var userPreferences = UserPreferences.shared
|
||||||
@State var pushNotificationsService = PushNotificationsService.shared
|
@State var pushNotificationsService = PushNotificationsService.shared
|
||||||
|
@State var appIntentService = AppIntentService.shared
|
||||||
@State var watcher = StreamWatcher.shared
|
@State var watcher = StreamWatcher.shared
|
||||||
@State var quickLook = QuickLook.shared
|
@State var quickLook = QuickLook.shared
|
||||||
@State var theme = Theme.shared
|
@State var theme = Theme.shared
|
||||||
|
|
||||||
@State var selectedTab: Tab = .timeline
|
@State var selectedTab: AppTab = .timeline
|
||||||
@State var appRouterPath = RouterPath()
|
@State var appRouterPath = RouterPath()
|
||||||
|
|
||||||
@State var isSupporter: Bool = false
|
@State var isSupporter: Bool = false
|
||||||
|
@ -79,13 +81,16 @@ struct IceCubesApp: App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate {
|
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
func application(_: UIApplication,
|
func application(_: UIApplication,
|
||||||
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool
|
||||||
{
|
{
|
||||||
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
try? AVAudioSession.sharedInstance().setCategory(.ambient, options: .mixWithOthers)
|
||||||
try? AVAudioSession.sharedInstance().setActive(true)
|
try? AVAudioSession.sharedInstance().setActive(true)
|
||||||
PushNotificationsService.shared.setAccounts(accounts: AppAccountsManager.shared.pushAccounts)
|
PushNotificationsService.shared.setAccounts(accounts: AppAccountsManager.shared.pushAccounts)
|
||||||
|
Telemetry.setup()
|
||||||
|
Telemetry.signal("app.launched")
|
||||||
|
WishKit.configure(with: "AF21AE07-3BA9-4FE2-BFB1-59A3B3941730")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,4 +118,11 @@ class AppDelegate: NSObject, UIApplicationDelegate {
|
||||||
}
|
}
|
||||||
return configuration
|
return configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func buildMenu(with builder: UIMenuBuilder) {
|
||||||
|
super.buildMenu(with: builder)
|
||||||
|
builder.remove(menu: .document)
|
||||||
|
builder.remove(menu: .toolbar)
|
||||||
|
builder.remove(menu: .sidebar)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,43 +36,37 @@ public struct ReportView: View {
|
||||||
.navigationTitle("report.title")
|
.navigationTitle("report.title")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
.scrollDismissesKeyboard(.immediately)
|
.scrollDismissesKeyboard(.immediately)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
Button {
|
Button {
|
||||||
isSendingReport = true
|
isSendingReport = true
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let _: ReportSent =
|
let _: ReportSent =
|
||||||
try await client.post(endpoint: Statuses.report(accountId: status.account.id,
|
try await client.post(endpoint: Statuses.report(accountId: status.account.id,
|
||||||
statusId: status.id,
|
statusId: status.id,
|
||||||
comment: commentText))
|
comment: commentText))
|
||||||
dismiss()
|
dismiss()
|
||||||
isSendingReport = false
|
isSendingReport = false
|
||||||
} catch {
|
} catch {
|
||||||
isSendingReport = false
|
isSendingReport = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
if isSendingReport {
|
||||||
|
ProgressView()
|
||||||
|
} else {
|
||||||
|
Text("report.action.send")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
|
||||||
if isSendingReport {
|
|
||||||
ProgressView()
|
|
||||||
} else {
|
|
||||||
Text("report.action.send")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
CancelToolbarItem()
|
||||||
Button {
|
|
||||||
dismiss()
|
|
||||||
} label: {
|
|
||||||
Text("action.cancel")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ import Models
|
||||||
import Observation
|
import Observation
|
||||||
import SafariServices
|
import SafariServices
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AppAccount
|
||||||
|
import WebKit
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
@MainActor func withSafariRouter() -> some View {
|
@MainActor func withSafariRouter() -> some View {
|
||||||
|
@ -13,25 +15,35 @@ extension View {
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
private struct SafariRouter: ViewModifier {
|
private struct SafariRouter: ViewModifier {
|
||||||
|
@Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
|
||||||
@Environment(Theme.self) private var theme
|
@Environment(Theme.self) private var theme
|
||||||
@Environment(UserPreferences.self) private var preferences
|
@Environment(UserPreferences.self) private var preferences
|
||||||
@Environment(RouterPath.self) private var routerPath
|
@Environment(RouterPath.self) private var routerPath
|
||||||
|
@Environment(AppAccountsManager.self) private var appAccount
|
||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
@State private var safariManager = InAppSafariManager()
|
@State private var safariManager = InAppSafariManager()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
content
|
content
|
||||||
.environment(\.openURL, OpenURLAction { url in
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
// Open internal URL.
|
// Open internal URL.
|
||||||
routerPath.handle(url: url)
|
guard !isSecondaryColumn else { return .discarded }
|
||||||
|
return routerPath.handle(url: url)
|
||||||
})
|
})
|
||||||
.onOpenURL { url in
|
.onOpenURL { url in
|
||||||
// Open external URL (from icecubesapp://)
|
// Open external URL (from icecubesapp://)
|
||||||
|
guard !isSecondaryColumn else { return }
|
||||||
|
if url.absoluteString == "icecubesapp://subclub" {
|
||||||
|
#if !os(visionOS)
|
||||||
|
safariManager.dismiss()
|
||||||
|
#endif
|
||||||
|
return
|
||||||
|
}
|
||||||
let urlString = url.absoluteString.replacingOccurrences(of: AppInfo.scheme, with: "https://")
|
let urlString = url.absoluteString.replacingOccurrences(of: AppInfo.scheme, with: "https://")
|
||||||
guard let url = URL(string: urlString), url.host != nil else { return }
|
guard let url = URL(string: urlString), url.host != nil else { return }
|
||||||
_ = routerPath.handle(url: url)
|
_ = routerPath.handleDeepLink(url: url)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
routerPath.urlHandler = { url in
|
routerPath.urlHandler = { url in
|
||||||
|
@ -44,6 +56,19 @@ private struct SafariRouter: ViewModifier {
|
||||||
UIApplication.shared.open(url)
|
UIApplication.shared.open(url)
|
||||||
return .handled
|
return .handled
|
||||||
}
|
}
|
||||||
|
} else if url.query()?.contains("callback=") == false,
|
||||||
|
url.host() == AppInfo.premiumInstance,
|
||||||
|
let accountName = appAccount.currentAccount.accountName {
|
||||||
|
let newURL = url.appending(queryItems: [
|
||||||
|
.init(name: "callback", value: "icecubesapp://subclub"),
|
||||||
|
.init(name: "id", value: "@\(accountName)")
|
||||||
|
])
|
||||||
|
|
||||||
|
#if !os(visionOS)
|
||||||
|
return safariManager.open(newURL)
|
||||||
|
#else
|
||||||
|
return .systemAction
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#if !targetEnvironment(macCatalyst)
|
#if !targetEnvironment(macCatalyst)
|
||||||
guard preferences.preferredBrowser == .inAppSafari else { return .systemAction }
|
guard preferences.preferredBrowser == .inAppSafari else { return .systemAction }
|
||||||
|
@ -52,78 +77,85 @@ private struct SafariRouter: ViewModifier {
|
||||||
return .systemAction
|
return .systemAction
|
||||||
}
|
}
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
return .systemAction
|
return .systemAction
|
||||||
#else
|
#else
|
||||||
return safariManager.open(url)
|
return safariManager.open(url)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
return .systemAction
|
return .systemAction
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.background {
|
.background {
|
||||||
WindowReader { window in
|
WindowReader { window in
|
||||||
safariManager.windowScene = window.windowScene
|
safariManager.windowScene = window.windowScene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
@MainActor
|
|
||||||
@Observable private class InAppSafariManager: NSObject, SFSafariViewControllerDelegate {
|
|
||||||
var windowScene: UIWindowScene?
|
|
||||||
let viewController: UIViewController = .init()
|
|
||||||
var window: UIWindow?
|
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
func open(_ url: URL) -> OpenURLAction.Result {
|
@Observable private class InAppSafariManager: NSObject, SFSafariViewControllerDelegate {
|
||||||
guard let windowScene else { return .systemAction }
|
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()
|
window = setupWindow(windowScene: windowScene)
|
||||||
configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView
|
|
||||||
|
|
||||||
let safari = SFSafariViewController(url: url, configuration: configuration)
|
let configuration = SFSafariViewController.Configuration()
|
||||||
safari.preferredBarTintColor = UIColor(Theme.shared.primaryBackgroundColor)
|
configuration.entersReaderIfAvailable = UserPreferences.shared.inAppBrowserReaderView
|
||||||
safari.preferredControlTintColor = UIColor(Theme.shared.tintColor)
|
|
||||||
safari.delegate = self
|
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
let safari = SFSafariViewController(url: url, configuration: configuration)
|
||||||
self?.viewController.present(safari, animated: true)
|
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 dismiss() {
|
||||||
}
|
viewController.presentedViewController?.dismiss(animated: true)
|
||||||
|
|
||||||
func setupWindow(windowScene: UIWindowScene) -> UIWindow {
|
|
||||||
let window = window ?? UIWindow(windowScene: windowScene)
|
|
||||||
|
|
||||||
window.rootViewController = viewController
|
|
||||||
window.makeKeyAndVisible()
|
|
||||||
|
|
||||||
switch Theme.shared.selectedScheme {
|
|
||||||
case .dark:
|
|
||||||
window.overrideUserInterfaceStyle = .dark
|
|
||||||
case .light:
|
|
||||||
window.overrideUserInterfaceStyle = .light
|
|
||||||
}
|
|
||||||
|
|
||||||
self.window = window
|
|
||||||
return window
|
|
||||||
}
|
|
||||||
|
|
||||||
nonisolated func safariViewControllerDidFinish(_: SFSafariViewController) {
|
|
||||||
Task { @MainActor in
|
|
||||||
window?.resignKey()
|
window?.resignKey()
|
||||||
window?.isHidden = false
|
window?.isHidden = false
|
||||||
window = nil
|
window = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupWindow(windowScene: UIWindowScene) -> UIWindow {
|
||||||
|
let window = window ?? UIWindow(windowScene: windowScene)
|
||||||
|
|
||||||
|
window.rootViewController = viewController
|
||||||
|
window.makeKeyAndVisible()
|
||||||
|
|
||||||
|
switch Theme.shared.selectedScheme {
|
||||||
|
case .dark:
|
||||||
|
window.overrideUserInterfaceStyle = .dark
|
||||||
|
case .light:
|
||||||
|
window.overrideUserInterfaceStyle = .light
|
||||||
|
}
|
||||||
|
|
||||||
|
self.window = window
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
|
||||||
|
nonisolated func safariViewControllerDidFinish(_: SFSafariViewController) {
|
||||||
|
Task { @MainActor in
|
||||||
|
window?.resignKey()
|
||||||
|
window?.isHidden = false
|
||||||
|
window = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private struct WindowReader: UIViewRepresentable {
|
private struct WindowReader: UIViewRepresentable {
|
||||||
|
|
|
@ -18,14 +18,13 @@ struct SideBarView<Content: View>: View {
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
@Environment(UserPreferences.self) private var userPreferences
|
||||||
@Environment(RouterPath.self) private var routerPath
|
@Environment(RouterPath.self) private var routerPath
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: AppTab
|
||||||
@Binding var popToRootTab: Tab
|
var tabs: [AppTab]
|
||||||
var tabs: [Tab]
|
|
||||||
@ViewBuilder var content: () -> Content
|
@ViewBuilder var content: () -> Content
|
||||||
|
|
||||||
@State private var sidebarTabs = SidebarTabs.shared
|
@State private var sidebarTabs = SidebarTabs.shared
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
private func badgeFor(tab: AppTab) -> Int {
|
||||||
if tab == .notifications, selectedTab != tab,
|
if tab == .notifications, selectedTab != tab,
|
||||||
let token = appAccounts.currentAccount.oauthToken
|
let token = appAccounts.currentAccount.oauthToken
|
||||||
{
|
{
|
||||||
|
@ -34,17 +33,32 @@ struct SideBarView<Content: View>: View {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeIconForTab(tab: Tab) -> some View {
|
private func makeIconForTab(tab: AppTab) -> some View {
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack(alignment: .topTrailing) {
|
||||||
SideBarIcon(systemIconName: tab.iconName,
|
HStack {
|
||||||
isSelected: tab == selectedTab)
|
SideBarIcon(systemIconName: tab.iconName,
|
||||||
|
isSelected: tab == selectedTab)
|
||||||
|
if userPreferences.isSidebarExpanded {
|
||||||
|
Text(tab.title)
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(tab == selectedTab ? theme.tintColor : theme.labelColor)
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: (userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth) - 24, height: 50)
|
||||||
|
.background(tab == selectedTab ? theme.primaryBackgroundColor : .clear,
|
||||||
|
in: RoundedRectangle(cornerRadius: 8))
|
||||||
|
.cornerRadius(8)
|
||||||
|
.shadow(color: tab == selectedTab ? .black.opacity(0.2) : .clear, radius: 5)
|
||||||
|
.overlay(
|
||||||
|
RoundedRectangle(cornerRadius: 8)
|
||||||
|
.stroke(tab == selectedTab ? theme.labelColor.opacity(0.1) : .clear, lineWidth: 1)
|
||||||
|
)
|
||||||
let badge = badgeFor(tab: tab)
|
let badge = badgeFor(tab: tab)
|
||||||
if badge > 0 {
|
if badge > 0 {
|
||||||
makeBadgeView(count: badge)
|
makeBadgeView(count: badge)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.contentShape(Rectangle())
|
|
||||||
.frame(width: .sidebarWidth, height: 50)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeBadgeView(count: Int) -> some View {
|
private func makeBadgeView(count: Int) -> some View {
|
||||||
|
@ -56,7 +70,7 @@ struct SideBarView<Content: View>: View {
|
||||||
.font(.caption2)
|
.font(.caption2)
|
||||||
}
|
}
|
||||||
.frame(width: 24, height: 24)
|
.frame(width: 24, height: 24)
|
||||||
.offset(x: 14, y: -14)
|
.offset(x: 5, y: -5)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var postButton: some View {
|
private var postButton: some View {
|
||||||
|
@ -74,6 +88,7 @@ struct SideBarView<Content: View>: View {
|
||||||
.offset(x: 2, y: -2)
|
.offset(x: 2, y: -2)
|
||||||
}
|
}
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
|
.help(AppTab.post.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
||||||
|
@ -90,9 +105,19 @@ struct SideBarView<Content: View>: View {
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack(alignment: .topTrailing) {
|
||||||
AppAccountView(viewModel: .init(appAccount: account, isCompact: true),
|
if userPreferences.isSidebarExpanded {
|
||||||
isParentPresented: .constant(false))
|
AppAccountView(viewModel: .init(appAccount: account,
|
||||||
if showBadge,
|
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 token = account.oauthToken,
|
||||||
let notificationsCount = userPreferences.notificationsCount[token],
|
let notificationsCount = userPreferences.notificationsCount[token],
|
||||||
notificationsCount > 0
|
notificationsCount > 0
|
||||||
|
@ -100,26 +125,29 @@ struct SideBarView<Content: View>: View {
|
||||||
makeBadgeView(count: notificationsCount)
|
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)
|
.padding(.vertical, 8)
|
||||||
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
.background(selectedTab == .profile && account.id == appAccounts.currentAccount.id ?
|
||||||
theme.secondaryBackgroundColor : .clear)
|
theme.secondaryBackgroundColor : .clear)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func accountButtonTitle(accountName: String?) -> LocalizedStringKey {
|
||||||
|
if let accountName {
|
||||||
|
"tab.profile-account-\(accountName)"
|
||||||
|
} else {
|
||||||
|
AppTab.profile.title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var tabsView: some View {
|
private var tabsView: some View {
|
||||||
ForEach(tabs) { tab in
|
ForEach(tabs) { tab in
|
||||||
if tab != .profile && sidebarTabs.isEnabled(tab) {
|
if tab != .profile && sidebarTabs.isEnabled(tab) {
|
||||||
Button {
|
Button {
|
||||||
// ensure keyboard is always dismissed when selecting a tab
|
// ensure keyboard is always dismissed when selecting a tab
|
||||||
hideKeyboard()
|
hideKeyboard()
|
||||||
|
|
||||||
if tab == selectedTab {
|
|
||||||
popToRootTab = .other
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
|
|
||||||
popToRootTab = tab
|
|
||||||
}
|
|
||||||
}
|
|
||||||
selectedTab = tab
|
selectedTab = tab
|
||||||
SoundEffectManager.shared.playSound(.tabSelection)
|
SoundEffectManager.shared.playSound(.tabSelection)
|
||||||
if tab == .notifications {
|
if tab == .notifications {
|
||||||
|
@ -131,7 +159,7 @@ struct SideBarView<Content: View>: View {
|
||||||
} label: {
|
} label: {
|
||||||
makeIconForTab(tab: tab)
|
makeIconForTab(tab: tab)
|
||||||
}
|
}
|
||||||
.background(tab == selectedTab ? theme.secondaryBackgroundColor : .clear)
|
.help(tab.title)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,15 +181,27 @@ struct SideBarView<Content: View>: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postButton
|
|
||||||
.padding(.top, 12)
|
|
||||||
Spacer()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(width: .sidebarWidth)
|
.frame(width: userPreferences.isSidebarExpanded ? .sidebarWidthExpanded : .sidebarWidth)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(.thinMaterial)
|
.background(.thinMaterial)
|
||||||
Divider().edgesIgnoringSafeArea(.all)
|
.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)
|
||||||
}
|
}
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
|
@ -191,6 +231,7 @@ private struct SideBarIcon: View {
|
||||||
self.isHovered = isHovered
|
self.isHovered = isHovered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.frame(width: 50, height: 40)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import Env
|
||||||
import Explore
|
import Explore
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@ -14,30 +13,19 @@ struct ExploreTab: View {
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
@Environment(Client.self) private var client
|
@Environment(Client.self) private var client
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
ExploreView(scrollToTopSignal: $scrollToTopSignal)
|
ExploreView()
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarTab(routerPath: $routerPath)
|
ToolbarTab(routerPath: $routerPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .explore {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@ -16,29 +15,18 @@ struct MessagesTab: View {
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
@Environment(AppAccountsManager.self) private var appAccount
|
@Environment(AppAccountsManager.self) private var appAccount
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
ConversationsListView(scrollToTopSignal: $scrollToTopSignal)
|
ConversationsListView()
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarTab(routerPath: $routerPath)
|
ToolbarTab(routerPath: $routerPath)
|
||||||
}
|
}
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.id(client.id)
|
.id(client.id)
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .messages {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import SwiftUI
|
|
||||||
import Env
|
|
||||||
import AppAccount
|
import AppAccount
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct NavigationSheet<Content: View>: View {
|
struct NavigationSheet<Content: View>: View {
|
||||||
|
@ -17,13 +17,7 @@ struct NavigationSheet<Content: View>: View {
|
||||||
NavigationStack {
|
NavigationStack {
|
||||||
content()
|
content()
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
CloseToolbarItem()
|
||||||
Button {
|
|
||||||
dismiss()
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "xmark.circle")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import SwiftUI
|
|
||||||
import Env
|
|
||||||
import AppAccount
|
import AppAccount
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
import Network
|
import Network
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct NavigationTab<Content: View>: View {
|
struct NavigationTab<Content: View>: View {
|
||||||
|
@ -32,7 +32,7 @@ struct NavigationTab<Content: View>: View {
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarTab(routerPath: $routerPath)
|
ToolbarTab(routerPath: $routerPath)
|
||||||
}
|
}
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,16 +20,14 @@ struct NotificationsTab: View {
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
@Environment(UserPreferences.self) private var userPreferences
|
||||||
@Environment(PushNotificationsService.self) private var pushNotificationsService
|
@Environment(PushNotificationsService.self) private var pushNotificationsService
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: AppTab
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
let lockedType: Models.Notification.NotificationType?
|
let lockedType: Models.Notification.NotificationType?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
NotificationsListView(lockedType: lockedType, scrollToTopSignal: $scrollToTopSignal)
|
NotificationsListView(lockedType: lockedType)
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
|
@ -42,7 +40,7 @@ struct NotificationsTab: View {
|
||||||
}
|
}
|
||||||
ToolbarTab(routerPath: $routerPath)
|
ToolbarTab(routerPath: $routerPath)
|
||||||
}
|
}
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.id(client.id)
|
.id(client.id)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
|
@ -51,18 +49,9 @@ struct NotificationsTab: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
.onChange(of: selectedTab) { _, _ in
|
||||||
if newValue == .notifications {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: selectedTab, { _, newValue in
|
|
||||||
clearNotifications()
|
clearNotifications()
|
||||||
})
|
}
|
||||||
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
|
.onChange(of: pushNotificationsService.handledNotification) { _, newValue in
|
||||||
if let newValue, let type = newValue.notification.supportedType {
|
if let newValue, let type = newValue.notification.supportedType {
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
|
||||||
|
@ -92,10 +81,12 @@ struct NotificationsTab: View {
|
||||||
|
|
||||||
private func clearNotifications() {
|
private func clearNotifications() {
|
||||||
if selectedTab == .notifications || isSecondaryColumn {
|
if selectedTab == .notifications || isSecondaryColumn {
|
||||||
if let token = appAccount.currentAccount.oauthToken {
|
if let token = appAccount.currentAccount.oauthToken, userPreferences.notificationsCount[token] ?? 0 > 0 {
|
||||||
userPreferences.notificationsCount[token] = 0
|
userPreferences.notificationsCount[token] = 0
|
||||||
}
|
}
|
||||||
watcher.unreadNotificationsCount = 0
|
if watcher.unreadNotificationsCount > 0 {
|
||||||
|
watcher.unreadNotificationsCount = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@ -15,32 +14,21 @@ struct ProfileTab: View {
|
||||||
@Environment(Client.self) private var client
|
@Environment(Client.self) private var client
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@State private var scrollToTopSignal: Int = 0
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
if let account = currentAccount.account {
|
if let account = currentAccount.account {
|
||||||
AccountDetailView(account: account, scrollToTopSignal: $scrollToTopSignal)
|
AccountDetailView(account: account)
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.id(account.id)
|
.id(account.id)
|
||||||
} else {
|
} else {
|
||||||
AccountDetailView(account: .placeholder(), scrollToTopSignal: $scrollToTopSignal)
|
AccountDetailView(account: .placeholder())
|
||||||
.redacted(reason: .placeholder)
|
.redacted(reason: .placeholder)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .profile {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,27 +27,27 @@ struct AboutView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
Section {
|
Section {
|
||||||
#if !targetEnvironment(macCatalyst)
|
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
||||||
HStack {
|
HStack {
|
||||||
Spacer()
|
Spacer()
|
||||||
Image(uiImage: .init(named: "AppIconAlternate0")!)
|
Image(uiImage: .init(named: "AppIconAlternate0-image") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate4")!)
|
Image(uiImage: .init(named: "AppIconAlternate46-image") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate17")!)
|
Image(uiImage: .init(named: "AppIconAlternate17-image") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Image(uiImage: .init(named: "AppIconAlternate23")!)
|
Image(uiImage: .init(named: "AppIconAlternate23-image") ?? .init())
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 50, height: 50)
|
.frame(width: 50, height: 50)
|
||||||
.cornerRadius(4)
|
.cornerRadius(4)
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp/blob/main/PRIVACY.MD")!) {
|
Link(destination: URL(string: "https://github.com/Dimillian/IceCubesApp/blob/main/PRIVACY.MD")!) {
|
||||||
Label("settings.support.privacy-policy", systemImage: "lock")
|
Label("settings.support.privacy-policy", systemImage: "lock")
|
||||||
|
@ -57,7 +57,7 @@ struct AboutView: View {
|
||||||
Label("settings.support.terms-of-use", systemImage: "checkmark.shield")
|
Label("settings.support.terms-of-use", systemImage: "checkmark.shield")
|
||||||
}
|
}
|
||||||
} footer: {
|
} footer: {
|
||||||
Text("\(versionNumber)©2023 Thomas Ricouard")
|
Text("\(versionNumber)© 2024 Thomas Ricouard")
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
@ -65,6 +65,18 @@ struct AboutView: View {
|
||||||
|
|
||||||
followAccountsSection
|
followAccountsSection
|
||||||
|
|
||||||
|
Section("Telemetry") {
|
||||||
|
Link(destination: .init(string: "https://telemetrydeck.com")!) {
|
||||||
|
Label("Telemetry by TelemetryDeck", systemImage: "link")
|
||||||
|
}
|
||||||
|
Link(destination: .init(string: "https://telemetrydeck.com/privacy/")!) {
|
||||||
|
Label("Privacy Policy", systemImage: "checkmark.shield")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
Text("""
|
Text("""
|
||||||
• [EmojiText](https://github.com/divadretlaw/EmojiText)
|
• [EmojiText](https://github.com/divadretlaw/EmojiText)
|
||||||
|
@ -107,14 +119,14 @@ struct AboutView: View {
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.navigationTitle(Text("settings.about.title"))
|
.navigationTitle(Text("settings.about.title"))
|
||||||
.navigationBarTitleDisplayMode(.large)
|
.navigationBarTitleDisplayMode(.large)
|
||||||
.environment(\.openURL, OpenURLAction { url in
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
routerPath.handle(url: url)
|
routerPath.handle(url: url)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
|
@ -140,13 +152,13 @@ struct AboutView: View {
|
||||||
private func fetchAccounts() async {
|
private func fetchAccounts() async {
|
||||||
await withThrowingTaskGroup(of: Void.self) { group in
|
await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
group.addTask {
|
group.addTask {
|
||||||
let viewModel = try await fetchAccountViewModel(account: "dimillian@mastodon.social")
|
let viewModel = try await fetchAccountViewModel(client, account: "dimillian@mastodon.social")
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
dimillianAccount = viewModel
|
dimillianAccount = viewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.addTask {
|
group.addTask {
|
||||||
let viewModel = try await fetchAccountViewModel(account: "icecubesapp@mastodon.online")
|
let viewModel = try await fetchAccountViewModel(client, account: "icecubesapp@mastodon.online")
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
iceCubesAccount = viewModel
|
iceCubesAccount = viewModel
|
||||||
}
|
}
|
||||||
|
@ -154,7 +166,7 @@ struct AboutView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func fetchAccountViewModel(account: String) async throws -> AccountsListRowViewModel {
|
private func fetchAccountViewModel(_ client: Client, account: String) async throws -> AccountsListRowViewModel {
|
||||||
let dimillianAccount: Account = try await client.get(endpoint: Accounts.lookup(name: account))
|
let dimillianAccount: Account = try await client.get(endpoint: Accounts.lookup(name: account))
|
||||||
let rel: [Relationship] = try await client.get(endpoint: Accounts.relationships(ids: [dimillianAccount.id]))
|
let rel: [Relationship] = try await client.get(endpoint: Accounts.relationships(ids: [dimillianAccount.id]))
|
||||||
return .init(account: dimillianAccount, relationShip: rel.first)
|
return .init(account: dimillianAccount, relationShip: rel.first)
|
||||||
|
|
|
@ -17,9 +17,8 @@ struct AccountSettingsView: View {
|
||||||
@Environment(Theme.self) private var theme
|
@Environment(Theme.self) private var theme
|
||||||
@Environment(AppAccountsManager.self) private var appAccountsManager
|
@Environment(AppAccountsManager.self) private var appAccountsManager
|
||||||
@Environment(Client.self) private var client
|
@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 cachedPostsCount: Int = 0
|
||||||
@State private var timelineCache = TimelineCache()
|
@State private var timelineCache = TimelineCache()
|
||||||
|
|
||||||
|
@ -30,7 +29,7 @@ struct AccountSettingsView: View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Button {
|
Button {
|
||||||
isEditingAccount = true
|
routerPath.presentedSheet = .accountEditInfo
|
||||||
} label: {
|
} label: {
|
||||||
Label("account.action.edit-info", systemImage: "pencil")
|
Label("account.action.edit-info", systemImage: "pencil")
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
@ -40,7 +39,7 @@ struct AccountSettingsView: View {
|
||||||
|
|
||||||
if currentInstance.isFiltersSupported {
|
if currentInstance.isFiltersSupported {
|
||||||
Button {
|
Button {
|
||||||
isEditingFilters = true
|
routerPath.presentedSheet = .accountFiltersList
|
||||||
} label: {
|
} label: {
|
||||||
Label("account.action.edit-filters", systemImage: "line.3.horizontal.decrease.circle")
|
Label("account.action.edit-filters", systemImage: "line.3.horizontal.decrease.circle")
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
@ -86,22 +85,17 @@ struct AccountSettingsView: View {
|
||||||
await sub.deleteSubscription()
|
await sub.deleteSubscription()
|
||||||
}
|
}
|
||||||
appAccountsManager.delete(account: appAccount)
|
appAccountsManager.delete(account: appAccount)
|
||||||
|
Telemetry.signal("account.removed")
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Text("account.action.logout")
|
Label("account.action.logout", systemImage: "trash")
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $isEditingAccount, content: {
|
|
||||||
EditAccountView()
|
|
||||||
})
|
|
||||||
.sheet(isPresented: $isEditingFilters, content: {
|
|
||||||
FiltersListView()
|
|
||||||
})
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .principal) {
|
ToolbarItem(placement: .principal) {
|
||||||
HStack {
|
HStack {
|
||||||
|
@ -116,8 +110,8 @@ struct AccountSettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle(account.safeDisplayName)
|
.navigationTitle(account.safeDisplayName)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import AppAccount
|
import AppAccount
|
||||||
|
import AuthenticationServices
|
||||||
import Combine
|
import Combine
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
|
@ -6,15 +7,14 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import SafariServices
|
import SafariServices
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct AddAccountView: View {
|
struct AddAccountView: View {
|
||||||
|
@Environment(\.webAuthenticationSession) private var webAuthenticationSession
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
@Environment(\.openURL) private var openURL
|
@Environment(\.openURL) private var openURL
|
||||||
@Environment(\.webAuthenticationSession) private var webAuthenticationSession
|
|
||||||
|
|
||||||
@Environment(AppAccountsManager.self) private var appAccountsManager
|
@Environment(AppAccountsManager.self) private var appAccountsManager
|
||||||
@Environment(CurrentAccount.self) private var currentAccount
|
@Environment(CurrentAccount.self) private var currentAccount
|
||||||
|
@ -83,77 +83,77 @@ struct AddAccountView: View {
|
||||||
.navigationTitle("account.add.navigation-title")
|
.navigationTitle("account.add.navigation-title")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
.scrollDismissesKeyboard(.immediately)
|
.scrollDismissesKeyboard(.immediately)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
if !appAccountsManager.availableAccounts.isEmpty {
|
CancelToolbarItem()
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
|
||||||
Button("action.cancel", action: { dismiss() })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
.onAppear {
|
||||||
.onAppear {
|
isInstanceURLFieldFocused = true
|
||||||
isInstanceURLFieldFocused = true
|
let instanceName = instanceName
|
||||||
Task {
|
Task {
|
||||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||||
withAnimation {
|
withAnimation {
|
||||||
self.instances = instances
|
self.instances = instances
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
isSigninIn = false
|
||||||
}
|
}
|
||||||
isSigninIn = false
|
.onChange(of: instanceName) {
|
||||||
}
|
searchingTask.cancel()
|
||||||
.onChange(of: instanceName) {
|
let instanceName = instanceName
|
||||||
searchingTask.cancel()
|
let instanceSocialClient = instanceSocialClient
|
||||||
searchingTask = Task {
|
searchingTask = Task {
|
||||||
try? await Task.sleep(for: .seconds(0.1))
|
try? await Task.sleep(for: .seconds(0.1))
|
||||||
guard !Task.isCancelled else { return }
|
guard !Task.isCancelled else { return }
|
||||||
|
|
||||||
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
let instances = await instanceSocialClient.fetchInstances(keyword: instanceName)
|
||||||
withAnimation {
|
withAnimation {
|
||||||
self.instances = instances
|
self.instances = instances
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getInstanceDetailTask.cancel()
|
getInstanceDetailTask.cancel()
|
||||||
getInstanceDetailTask = Task {
|
getInstanceDetailTask = Task {
|
||||||
try? await Task.sleep(for: .seconds(0.1))
|
try? await Task.sleep(for: .seconds(0.1))
|
||||||
guard !Task.isCancelled else { return }
|
guard !Task.isCancelled else { return }
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// bare bones preflight for domain validity
|
// bare bones preflight for domain validity
|
||||||
let instanceDetailClient = Client(server: sanitizedName)
|
let instanceDetailClient = Client(server: sanitizedName)
|
||||||
if
|
if
|
||||||
instanceDetailClient.server.contains("."),
|
instanceDetailClient.server.contains("."),
|
||||||
instanceDetailClient.server.last != "."
|
instanceDetailClient.server.last != "."
|
||||||
{
|
{
|
||||||
let instance: Instance = try await instanceDetailClient.get(endpoint: Instances.instance)
|
let instance: Instance = try await instanceDetailClient.get(endpoint: Instances.instance)
|
||||||
withAnimation {
|
withAnimation {
|
||||||
self.instance = instance
|
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
|
self.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
|
||||||
}
|
}
|
||||||
instanceFetchError = nil
|
} catch _ as ServerError {
|
||||||
} else {
|
instance = nil
|
||||||
|
instanceFetchError = "account.add.error.instance-not-supported"
|
||||||
|
} catch {
|
||||||
instance = nil
|
instance = nil
|
||||||
instanceFetchError = nil
|
instanceFetchError = nil
|
||||||
}
|
}
|
||||||
} catch _ as DecodingError {
|
|
||||||
instance = nil
|
|
||||||
instanceFetchError = "account.add.error.instance-not-supported"
|
|
||||||
} catch {
|
|
||||||
instance = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.onChange(of: scenePhase) { _, newValue in
|
||||||
.onChange(of: scenePhase) { _, newValue in
|
switch newValue {
|
||||||
switch newValue {
|
case .active:
|
||||||
case .active:
|
isSigninIn = false
|
||||||
isSigninIn = false
|
default:
|
||||||
default:
|
break
|
||||||
break
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,9 +217,9 @@ struct AddAccountView: View {
|
||||||
.foregroundColor(.primary)
|
.foregroundColor(.primary)
|
||||||
Spacer()
|
Spacer()
|
||||||
(Text("instance.list.users-\(formatAsNumber(instance.users))")
|
(Text("instance.list.users-\(formatAsNumber(instance.users))")
|
||||||
+ Text(" ⸱ ")
|
+ Text(" ⸱ ")
|
||||||
+ Text("instance.list.posts-\(formatAsNumber(instance.statuses))"))
|
+ Text("instance.list.posts-\(formatAsNumber(instance.statuses))"))
|
||||||
.foregroundStyle(theme.tintColor)
|
.foregroundStyle(theme.tintColor)
|
||||||
}
|
}
|
||||||
.padding(.bottom, 5)
|
.padding(.bottom, 5)
|
||||||
Text(instance.info?.shortDescription?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "")
|
Text(instance.info?.shortDescription?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "")
|
||||||
|
@ -265,9 +265,8 @@ struct AddAccountView: View {
|
||||||
}
|
}
|
||||||
.redacted(reason: .placeholder)
|
.redacted(reason: .placeholder)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
.shimmering()
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,6 +291,7 @@ struct AddAccountView: View {
|
||||||
let oauthToken = try await client.continueOauthFlow(url: url)
|
let oauthToken = try await client.continueOauthFlow(url: url)
|
||||||
let client = Client(server: client.server, oauthToken: oauthToken)
|
let client = Client(server: client.server, oauthToken: oauthToken)
|
||||||
let account: Account = try await client.get(endpoint: Accounts.verifyCredentials)
|
let account: Account = try await client.get(endpoint: Accounts.verifyCredentials)
|
||||||
|
Telemetry.signal("account.added")
|
||||||
appAccountsManager.add(account: AppAccount(server: client.server,
|
appAccountsManager.add(account: AppAccount(server: client.server,
|
||||||
accountName: "\(account.acct)@\(client.server)",
|
accountName: "\(account.acct)@\(client.server)",
|
||||||
oauthToken: oauthToken))
|
oauthToken: oauthToken))
|
||||||
|
@ -306,13 +306,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,8 +5,8 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UserNotifications
|
|
||||||
import Timeline
|
import Timeline
|
||||||
|
import UserNotifications
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct ContentSettingsView: View {
|
struct ContentSettingsView: View {
|
||||||
|
@ -41,7 +41,7 @@ struct ContentSettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ struct ContentSettingsView: View {
|
||||||
userPreferences.appAutoExpandMedia = userPreferences.autoExpandMedia
|
userPreferences.appAutoExpandMedia = userPreferences.autoExpandMedia
|
||||||
userPreferences.appDefaultPostsSensitive = userPreferences.postIsSensitive
|
userPreferences.appDefaultPostsSensitive = userPreferences.postIsSensitive
|
||||||
userPreferences.appDefaultPostVisibility = userPreferences.postVisibility
|
userPreferences.appDefaultPostVisibility = userPreferences.postVisibility
|
||||||
|
userPreferences.appRequireAltText = userPreferences.appRequireAltText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +113,10 @@ struct ContentSettingsView: View {
|
||||||
Text("settings.content.default-sensitive")
|
Text("settings.content.default-sensitive")
|
||||||
}
|
}
|
||||||
.disabled(userPreferences.useInstanceContentSettings)
|
.disabled(userPreferences.useInstanceContentSettings)
|
||||||
|
|
||||||
|
Toggle(isOn: $userPreferences.appRequireAltText) {
|
||||||
|
Text("settings.content.require-alt-text")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
@ -137,8 +142,8 @@ struct ContentSettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.content.navigation-title")
|
.navigationTitle("settings.content.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Observation
|
||||||
import StatusKit
|
import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@MainActor
|
||||||
@Observable class DisplaySettingsLocalValues {
|
@Observable class DisplaySettingsLocalValues {
|
||||||
var tintColor = Theme.shared.tintColor
|
var tintColor = Theme.shared.tintColor
|
||||||
var primaryBackgroundColor = Theme.shared.primaryBackgroundColor
|
var primaryBackgroundColor = Theme.shared.primaryBackgroundColor
|
||||||
|
@ -35,11 +36,13 @@ struct DisplaySettingsView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ZStack(alignment: .top) {
|
ZStack(alignment: .top) {
|
||||||
Form {
|
Form {
|
||||||
StatusRowView(viewModel: previewStatusViewModel)
|
#if !os(visionOS)
|
||||||
.allowsHitTesting(false)
|
StatusRowExternalView(viewModel: previewStatusViewModel)
|
||||||
.opacity(0)
|
.allowsHitTesting(false)
|
||||||
.hidden()
|
.opacity(0)
|
||||||
themeSection
|
.hidden()
|
||||||
|
themeSection
|
||||||
|
#endif
|
||||||
fontSection
|
fontSection
|
||||||
layoutSection
|
layoutSection
|
||||||
platformsSection
|
platformsSection
|
||||||
|
@ -47,40 +50,42 @@ struct DisplaySettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.display.navigation-title")
|
.navigationTitle("settings.display.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.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
|
#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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var examplePost: some View {
|
private var examplePost: some View {
|
||||||
VStack(spacing: 0) {
|
VStack(spacing: 0) {
|
||||||
StatusRowView(viewModel: previewStatusViewModel)
|
StatusRowExternalView(viewModel: previewStatusViewModel)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
.padding(.layoutPadding)
|
.padding(.layoutPadding)
|
||||||
.background(theme.primaryBackgroundColor)
|
.background(theme.primaryBackgroundColor)
|
||||||
|
@ -232,6 +237,8 @@ struct DisplaySettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Toggle("settings.display.show-account-popover", isOn: $userPreferences.showAccountPopover)
|
Toggle("settings.display.show-account-popover", isOn: $userPreferences.showAccountPopover)
|
||||||
|
Toggle("Show Content Gradient", isOn: $theme.showContentGradient)
|
||||||
|
Toggle("Compact Layout", isOn: $theme.compactLayoutPadding)
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
|
@ -23,8 +23,8 @@ struct HapticSettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.haptic.navigation-title")
|
.navigationTitle("settings.haptic.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,16 @@ struct IconSelectorView: View {
|
||||||
case alt38
|
case alt38
|
||||||
case alt39, alt40, alt41, alt42, alt43
|
case alt39, alt40, alt41, alt42, alt43
|
||||||
case alt44, alt45
|
case alt44, alt45
|
||||||
|
case alt46, alt47, alt48
|
||||||
|
case alt49
|
||||||
|
|
||||||
var appIconName: String {
|
var appIconName: String {
|
||||||
return "AppIconAlternate\(rawValue)"
|
return "AppIconAlternate\(rawValue)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var previewImageName: String {
|
||||||
|
return "AppIconAlternate\(rawValue)-image"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct IconSelector: Identifiable {
|
struct IconSelector: Identifiable {
|
||||||
|
@ -39,7 +45,7 @@ struct IconSelectorView: View {
|
||||||
|
|
||||||
static let items = [
|
static let items = [
|
||||||
IconSelector(title: "settings.app.icon.official".localized, icons: [
|
IconSelector(title: "settings.app.icon.official".localized, icons: [
|
||||||
.primary, .alt1, .alt2, .alt3, .alt4,
|
.primary, .alt46, .alt1, .alt2, .alt3, .alt4,
|
||||||
.alt5, .alt6, .alt7, .alt8,
|
.alt5, .alt6, .alt7, .alt8,
|
||||||
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14, .alt15,
|
.alt9, .alt10, .alt11, .alt12, .alt13, .alt14, .alt15,
|
||||||
.alt16, .alt17, .alt18, .alt19, .alt20, .alt21]),
|
.alt16, .alt17, .alt18, .alt19, .alt20, .alt21]),
|
||||||
|
@ -50,6 +56,8 @@ struct IconSelectorView: View {
|
||||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Duncan Horne", icons: [.alt38]),
|
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) BeAware@social.beaware.live", icons: [.alt39, .alt40, .alt41, .alt42, .alt43]),
|
||||||
IconSelector(title: "\("settings.app.icon.designed-by".localized) Simone Margio", icons: [.alt44, .alt45]),
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Simone Margio", icons: [.alt44, .alt45]),
|
||||||
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Peter Broqvist (@PKB)", icons: [.alt47, .alt48]),
|
||||||
|
IconSelector(title: "\("settings.app.icon.designed-by".localized) Oz Tsori (@oztsori)", icons: [.alt49]),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +101,7 @@ struct IconSelectorView: View {
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
ZStack(alignment: .bottomTrailing) {
|
ZStack(alignment: .bottomTrailing) {
|
||||||
Image(uiImage: .init(named: icon.appIconName) ?? .init())
|
Image(icon.previewImageName)
|
||||||
.resizable()
|
.resizable()
|
||||||
.aspectRatio(contentMode: .fit)
|
.aspectRatio(contentMode: .fit)
|
||||||
.frame(minHeight: 125, maxHeight: 1024)
|
.frame(minHeight: 125, maxHeight: 1024)
|
||||||
|
|
|
@ -14,8 +14,8 @@ struct InstanceInfoView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("instance.info.navigation-title")
|
.navigationTitle("instance.info.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,12 +111,12 @@ struct PushNotificationsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.push.navigation-title")
|
.navigationTitle("settings.push.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.task {
|
.task {
|
||||||
await subscription.fetchSubscription()
|
await subscription.fetchSubscription()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateSubscription() {
|
private func updateSubscription() {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import SwiftUI
|
|
||||||
import SwiftData
|
|
||||||
import Models
|
|
||||||
import Env
|
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import Models
|
||||||
|
import SwiftData
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct RecenTagsSettingView: View {
|
struct RecenTagsSettingView: View {
|
||||||
@Environment(\.modelContext) private var context
|
@Environment(\.modelContext) private var context
|
||||||
|
@ -35,10 +35,10 @@ struct RecenTagsSettingView: View {
|
||||||
.navigationTitle("settings.general.recent-tags")
|
.navigationTitle("settings.general.recent-tags")
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
EditButton()
|
EditButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import SwiftUI
|
|
||||||
import SwiftData
|
|
||||||
import Models
|
|
||||||
import Env
|
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import Models
|
||||||
|
import SwiftData
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct RemoteTimelinesSettingView: View {
|
struct RemoteTimelinesSettingView: View {
|
||||||
@Environment(\.modelContext) private var context
|
@Environment(\.modelContext) private var context
|
||||||
|
@ -36,10 +36,10 @@ struct RemoteTimelinesSettingView: View {
|
||||||
.navigationTitle("settings.general.remote-timelines")
|
.navigationTitle("settings.general.remote-timelines")
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
EditButton()
|
EditButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,10 +28,10 @@ struct SettingsTabs: View {
|
||||||
@State private var cachedRemoved = false
|
@State private var cachedRemoved = false
|
||||||
@State private var timelineCache = TimelineCache()
|
@State private var timelineCache = TimelineCache()
|
||||||
|
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
let isModal: Bool
|
let isModal: Bool
|
||||||
|
|
||||||
|
@State private var startingPoint: SettingsStartingPoint? = nil
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationStack(path: $routerPath.path) {
|
NavigationStack(path: $routerPath.path) {
|
||||||
Form {
|
Form {
|
||||||
|
@ -39,31 +39,59 @@ struct SettingsTabs: View {
|
||||||
accountsSection
|
accountsSection
|
||||||
generalSection
|
generalSection
|
||||||
otherSections
|
otherSections
|
||||||
|
postStreamingSection
|
||||||
|
AISection
|
||||||
cacheSection
|
cacheSection
|
||||||
}
|
}
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.navigationTitle(Text("settings.title"))
|
.navigationTitle(Text("settings.title"))
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
if isModal {
|
if isModal {
|
||||||
ToolbarItem {
|
ToolbarItem {
|
||||||
Button {
|
Button {
|
||||||
dismiss()
|
dismiss()
|
||||||
} label: {
|
} label: {
|
||||||
Text("action.done").bold()
|
Text("action.done").bold()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn, !isModal {
|
||||||
|
SecondaryColumnToolbarItem()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if UIDevice.current.userInterfaceIdiom == .pad, !preferences.showiPadSecondaryColumn, !isModal {
|
.withAppRouter()
|
||||||
SecondaryColumnToolbarItem()
|
.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 {
|
.onAppear {
|
||||||
routerPath.client = client
|
routerPath.client = client
|
||||||
|
@ -75,11 +103,6 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .notifications {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var accountsSection: some View {
|
private var accountsSection: some View {
|
||||||
|
@ -108,10 +131,10 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addAccountButton
|
||||||
if !appAccountsManager.availableAccounts.isEmpty {
|
if !appAccountsManager.availableAccounts.isEmpty {
|
||||||
editAccountButton
|
editAccountButton
|
||||||
}
|
}
|
||||||
addAccountButton
|
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
@ -126,6 +149,7 @@ struct SettingsTabs: View {
|
||||||
await timelineCache.clearCache(for: client.id)
|
await timelineCache.clearCache(for: client.id)
|
||||||
await sub.deleteSubscription()
|
await sub.deleteSubscription()
|
||||||
appAccountsManager.delete(account: account)
|
appAccountsManager.delete(account: account)
|
||||||
|
Telemetry.signal("account.removed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,9 +230,6 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
.disabled(preferences.preferredBrowser != PreferredBrowser.inAppSafari)
|
.disabled(preferences.preferredBrowser != PreferredBrowser.inAppSafari)
|
||||||
#endif
|
#endif
|
||||||
Toggle(isOn: $preferences.isOpenAIEnabled) {
|
|
||||||
Label("settings.other.hide-openai", systemImage: "faxmachine")
|
|
||||||
}
|
|
||||||
Toggle(isOn: $preferences.isSocialKeyboardEnabled) {
|
Toggle(isOn: $preferences.isSocialKeyboardEnabled) {
|
||||||
Label("settings.other.social-keyboard", systemImage: "keyboard")
|
Label("settings.other.social-keyboard", systemImage: "keyboard")
|
||||||
}
|
}
|
||||||
|
@ -228,6 +249,40 @@ struct SettingsTabs: View {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private var postStreamingSection: some View {
|
||||||
|
@Bindable var preferences = preferences
|
||||||
|
Section {
|
||||||
|
Toggle(isOn: $preferences.isPostsStreamingEnabled) {
|
||||||
|
Label("Posts streaming", systemImage: "clock.badge")
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Text("Streaming")
|
||||||
|
} footer: {
|
||||||
|
Text("Enabling post streaming will automatically add new posts at the top of your home timeline. Disable if you get performance issues.")
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
private var AISection: some View {
|
||||||
|
@Bindable var preferences = preferences
|
||||||
|
Section {
|
||||||
|
Toggle(isOn: $preferences.isOpenAIEnabled) {
|
||||||
|
Label("settings.other.hide-openai", systemImage: "faxmachine")
|
||||||
|
}
|
||||||
|
} header: {
|
||||||
|
Text("AI")
|
||||||
|
} footer: {
|
||||||
|
Text("Disable to hide AI assisted tool options such as copywritting and alt-image description generated using AI. Uses OpenAI API. See our Privacy Policy for more information.")
|
||||||
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private var appSection: some View {
|
private var appSection: some View {
|
||||||
Section {
|
Section {
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
||||||
|
@ -236,10 +291,14 @@ struct SettingsTabs: View {
|
||||||
Text("settings.app.icon")
|
Text("settings.app.icon")
|
||||||
} icon: {
|
} icon: {
|
||||||
let icon = IconSelectorView.Icon(string: UIApplication.shared.alternateIconName ?? "AppIcon")
|
let icon = IconSelectorView.Icon(string: UIApplication.shared.alternateIconName ?? "AppIcon")
|
||||||
Image(uiImage: .init(named: icon.appIconName)!)
|
if let image: UIImage = .init(named: icon.previewImageName) {
|
||||||
.resizable()
|
Image(uiImage: image)
|
||||||
.frame(width: 25, height: 25)
|
.resizable()
|
||||||
.cornerRadius(4)
|
.frame(width: 25, height: 25)
|
||||||
|
.cornerRadius(4)
|
||||||
|
} else {
|
||||||
|
EmptyView()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -262,10 +321,18 @@ struct SettingsTabs: View {
|
||||||
.tint(theme.labelColor)
|
.tint(theme.labelColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationLink(destination: AboutView()) {
|
NavigationLink {
|
||||||
|
AboutView()
|
||||||
|
} label: {
|
||||||
Label("settings.app.about", systemImage: "info.circle")
|
Label("settings.app.about", systemImage: "info.circle")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NavigationLink {
|
||||||
|
WishlistView()
|
||||||
|
} label: {
|
||||||
|
Label("Feature Requests", systemImage: "list.bullet.rectangle.portrait")
|
||||||
|
}
|
||||||
|
|
||||||
} header: {
|
} header: {
|
||||||
Text("settings.section.app")
|
Text("settings.section.app")
|
||||||
} footer: {
|
} footer: {
|
||||||
|
@ -282,7 +349,7 @@ struct SettingsTabs: View {
|
||||||
Button {
|
Button {
|
||||||
addAccountSheetPresented.toggle()
|
addAccountSheetPresented.toggle()
|
||||||
} label: {
|
} label: {
|
||||||
Text("settings.account.add")
|
Label("settings.account.add", systemImage: "person.badge.plus")
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $addAccountSheetPresented) {
|
.sheet(isPresented: $addAccountSheetPresented) {
|
||||||
AddAccountView()
|
AddAccountView()
|
||||||
|
@ -290,21 +357,23 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private var editAccountButton: some View {
|
private var editAccountButton: some View {
|
||||||
Button(role: isEditingAccount ? .none : .destructive) {
|
Button(role: .destructive) {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
isEditingAccount.toggle()
|
isEditingAccount.toggle()
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
if isEditingAccount {
|
if isEditingAccount {
|
||||||
Text("action.done")
|
Label("action.done", systemImage: "person.badge.minus")
|
||||||
|
.foregroundStyle(.red)
|
||||||
} else {
|
} else {
|
||||||
Text("account.action.logout")
|
Label("account.action.logout", systemImage: "person.badge.minus")
|
||||||
|
.foregroundStyle(.red)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var cacheSection: some View {
|
private var cacheSection: some View {
|
||||||
Section("settings.section.cache") {
|
Section {
|
||||||
if cachedRemoved {
|
if cachedRemoved {
|
||||||
Text("action.done")
|
Text("action.done")
|
||||||
.transition(.move(edge: .leading))
|
.transition(.move(edge: .leading))
|
||||||
|
@ -316,6 +385,10 @@ struct SettingsTabs: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} header: {
|
||||||
|
Text("settings.section.cache")
|
||||||
|
} footer: {
|
||||||
|
Text("Remove all cached images and videos")
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct SidebarEntriesSettingsView: View {
|
struct SidebarEntriesSettingsView: View {
|
||||||
@Environment(Theme.self) private var theme
|
@Environment(Theme.self) private var theme
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
@Environment(UserPreferences.self) private var userPreferences
|
||||||
|
@ -28,8 +29,8 @@ struct SidebarEntriesSettingsView: View {
|
||||||
.environment(\.editMode, .constant(.active))
|
.environment(\.editMode, .constant(.active))
|
||||||
.navigationTitle("settings.general.sidebarEntries")
|
.navigationTitle("settings.general.sidebarEntries")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Env
|
import Env
|
||||||
import RevenueCat
|
import RevenueCat
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@ -70,24 +69,24 @@ struct SupportAppView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.support.navigation-title")
|
.navigationTitle("settings.support.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.alert("settings.support.alert.title", isPresented: $purchaseSuccessDisplayed, actions: {
|
.alert("settings.support.alert.title", isPresented: $purchaseSuccessDisplayed, actions: {
|
||||||
Button { purchaseSuccessDisplayed = false } label: { Text("alert.button.ok") }
|
Button { purchaseSuccessDisplayed = false } label: { Text("alert.button.ok") }
|
||||||
}, message: {
|
}, message: {
|
||||||
Text("settings.support.alert.message")
|
Text("settings.support.alert.message")
|
||||||
})
|
})
|
||||||
.alert("alert.error", isPresented: $purchaseErrorDisplayed, actions: {
|
.alert("alert.error", isPresented: $purchaseErrorDisplayed, actions: {
|
||||||
Button { purchaseErrorDisplayed = false } label: { Text("alert.button.ok") }
|
Button { purchaseErrorDisplayed = false } label: { Text("alert.button.ok") }
|
||||||
}, message: {
|
}, message: {
|
||||||
Text("settings.support.alert.error.message")
|
Text("settings.support.alert.error.message")
|
||||||
})
|
})
|
||||||
.onAppear {
|
.onAppear {
|
||||||
loadingProducts = true
|
loadingProducts = true
|
||||||
fetchStoreProducts()
|
fetchStoreProducts()
|
||||||
refreshUserInfo()
|
refreshUserInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func purchase(product: StoreProduct) async {
|
private func purchase(product: StoreProduct) async {
|
||||||
|
@ -280,6 +279,5 @@ struct SupportAppView: View {
|
||||||
}
|
}
|
||||||
.redacted(reason: .placeholder)
|
.redacted(reason: .placeholder)
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
.shimmering()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,8 @@ struct SwipeActionsSettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.swipeactions.navigation-title")
|
.navigationTitle("settings.swipeactions.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,28 +14,38 @@ struct TabbarEntriesSettingsView: View {
|
||||||
Form {
|
Form {
|
||||||
Section {
|
Section {
|
||||||
Picker("settings.tabs.first-tab", selection: $tabs.firstTab) {
|
Picker("settings.tabs.first-tab", selection: $tabs.firstTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
if tab == tabs.firstTab || !tabs.tabs.contains(tab) {
|
||||||
|
tab.label.tag(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.second-tab", selection: $tabs.secondTab) {
|
Picker("settings.tabs.second-tab", selection: $tabs.secondTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
if tab == tabs.secondTab || !tabs.tabs.contains(tab) {
|
||||||
|
tab.label.tag(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.third-tab", selection: $tabs.thirdTab) {
|
Picker("settings.tabs.third-tab", selection: $tabs.thirdTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
if tab == tabs.thirdTab || !tabs.tabs.contains(tab) {
|
||||||
|
tab.label.tag(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.fourth-tab", selection: $tabs.fourthTab) {
|
Picker("settings.tabs.fourth-tab", selection: $tabs.fourthTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
if tab == tabs.fourthTab || !tabs.tabs.contains(tab) {
|
||||||
|
tab.label.tag(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Picker("settings.tabs.fifth-tab", selection: $tabs.fifthTab) {
|
Picker("settings.tabs.fifth-tab", selection: $tabs.fifthTab) {
|
||||||
ForEach(Tab.allCases) { tab in
|
ForEach(AppTab.allCases) { tab in
|
||||||
tab.label.tag(tab)
|
if tab == tabs.fifthTab || !tabs.tabs.contains(tab) {
|
||||||
|
tab.label.tag(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,8 +62,8 @@ struct TabbarEntriesSettingsView: View {
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.general.tabbarEntries")
|
.navigationTitle("settings.general.tabbarEntries")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import SwiftUI
|
|
||||||
import SwiftData
|
|
||||||
import Models
|
|
||||||
import Env
|
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import Models
|
||||||
|
import SwiftData
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct TagsGroupSettingView: View {
|
struct TagsGroupSettingView: View {
|
||||||
@Environment(\.modelContext) private var context
|
@Environment(\.modelContext) private var context
|
||||||
|
@ -41,10 +41,10 @@ struct TagsGroupSettingView: View {
|
||||||
.navigationTitle("timeline.filter.tag-groups")
|
.navigationTitle("timeline.filter.tag-groups")
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
EditButton()
|
EditButton()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,13 @@ struct TranslationSettingsView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
deepLToggle
|
translationSelector
|
||||||
if preferences.alwaysUseDeepl {
|
if preferences.preferredTranslationType == .useDeepl {
|
||||||
Section("settings.translation.user-api-key") {
|
Section("settings.translation.user-api-key") {
|
||||||
deepLPicker
|
deepLPicker
|
||||||
SecureField("settings.translation.user-api-key", text: $apiKey)
|
SecureField("settings.translation.user-api-key", text: $apiKey)
|
||||||
.textContentType(.password)
|
.textContentType(.password)
|
||||||
}
|
}
|
||||||
.onAppear {
|
|
||||||
readValue()
|
|
||||||
}
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,30 +34,51 @@ struct TranslationSettingsView: View {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
backgroundAPIKey
|
||||||
autoDetectSection
|
autoDetectSection
|
||||||
}
|
}
|
||||||
.navigationTitle("settings.translation.navigation-title")
|
.navigationTitle("settings.translation.navigation-title")
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
.onChange(of: apiKey) {
|
.onChange(of: apiKey) {
|
||||||
writeNewValue()
|
writeNewValue()
|
||||||
}
|
}
|
||||||
.onAppear(perform: updatePrefs)
|
.onAppear(perform: updatePrefs)
|
||||||
|
.onAppear(perform: readValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var deepLToggle: some View {
|
private var translationSelector: some View {
|
||||||
@Bindable var preferences = preferences
|
@Bindable var preferences = preferences
|
||||||
Toggle(isOn: $preferences.alwaysUseDeepl) {
|
Picker("Translation Service", selection: $preferences.preferredTranslationType) {
|
||||||
Text("settings.translation.always-deepl")
|
ForEach(allTTCases, id: \.self) { type in
|
||||||
|
Text(type.description).tag(type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
#endif
|
#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
|
@ViewBuilder
|
||||||
private var deepLPicker: some View {
|
private var deepLPicker: some View {
|
||||||
@Bindable var preferences = preferences
|
@Bindable var preferences = preferences
|
||||||
|
@ -80,6 +98,34 @@ struct TranslationSettingsView: View {
|
||||||
} footer: {
|
} footer: {
|
||||||
Text("settings.translation.auto-detect-post-language-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() {
|
private func writeNewValue() {
|
||||||
|
@ -91,11 +137,7 @@ struct TranslationSettingsView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func readValue() {
|
private func readValue() {
|
||||||
if let apiKey = DeepLUserAPIHandler.readIfAllowed() {
|
apiKey = DeepLUserAPIHandler.readKey()
|
||||||
self.apiKey = apiKey
|
|
||||||
} else {
|
|
||||||
apiKey = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updatePrefs() {
|
private func updatePrefs() {
|
||||||
|
|
8
IceCubesApp/App/Tabs/Settings/WishlistView.swift
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import SwiftUI
|
||||||
|
import WishKit
|
||||||
|
|
||||||
|
struct WishlistView: View {
|
||||||
|
var body: some View {
|
||||||
|
WishKit.view
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import Account
|
import Account
|
||||||
|
import AppIntents
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
import Explore
|
import Explore
|
||||||
import Foundation
|
import Foundation
|
||||||
|
@ -6,7 +7,7 @@ import StatusKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
enum AppTab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
case timeline, notifications, mentions, explore, messages, settings, other
|
case timeline, notifications, mentions, explore, messages, settings, other
|
||||||
case trending, federated, local
|
case trending, federated, local
|
||||||
case profile
|
case profile
|
||||||
|
@ -15,42 +16,43 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
case post
|
case post
|
||||||
case followedTags
|
case followedTags
|
||||||
case lists
|
case lists
|
||||||
|
case links
|
||||||
|
|
||||||
nonisolated var id: Int {
|
nonisolated var id: Int {
|
||||||
rawValue
|
rawValue
|
||||||
}
|
}
|
||||||
|
|
||||||
static func loggedOutTab() -> [Tab] {
|
static func loggedOutTab() -> [AppTab] {
|
||||||
[.timeline, .settings]
|
[.timeline, .settings]
|
||||||
}
|
}
|
||||||
|
|
||||||
static func visionOSTab() -> [Tab] {
|
static func visionOSTab() -> [AppTab] {
|
||||||
[.profile, .timeline, .notifications, .mentions, .explore, .messages, .settings]
|
[.profile, .timeline, .notifications, .mentions, .explore, .post, .settings]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func makeContentView(selectedTab: Binding<Tab>, popToRootTab: Binding<Tab>) -> some View {
|
func makeContentView(selectedTab: Binding<AppTab>) -> some View {
|
||||||
switch self {
|
switch self {
|
||||||
case .timeline:
|
case .timeline:
|
||||||
TimelineTab(popToRootTab: popToRootTab)
|
TimelineTab()
|
||||||
case .trending:
|
case .trending:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .trending)
|
TimelineTab(timeline: .trending)
|
||||||
case .local:
|
case .local:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .local)
|
TimelineTab(timeline: .local)
|
||||||
case .federated:
|
case .federated:
|
||||||
TimelineTab(popToRootTab: popToRootTab, timeline: .federated)
|
TimelineTab(timeline: .federated)
|
||||||
case .notifications:
|
case .notifications:
|
||||||
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: nil)
|
NotificationsTab(selectedTab: selectedTab, lockedType: nil)
|
||||||
case .mentions:
|
case .mentions:
|
||||||
NotificationsTab(selectedTab: selectedTab, popToRootTab: popToRootTab, lockedType: .mention)
|
NotificationsTab(selectedTab: selectedTab, lockedType: .mention)
|
||||||
case .explore:
|
case .explore:
|
||||||
ExploreTab(popToRootTab: popToRootTab)
|
ExploreTab()
|
||||||
case .messages:
|
case .messages:
|
||||||
MessagesTab(popToRootTab: popToRootTab)
|
MessagesTab()
|
||||||
case .settings:
|
case .settings:
|
||||||
SettingsTabs(popToRootTab: popToRootTab, isModal: false)
|
SettingsTabs(isModal: false)
|
||||||
case .profile:
|
case .profile:
|
||||||
ProfileTab(popToRootTab: popToRootTab)
|
ProfileTab()
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
NavigationTab {
|
NavigationTab {
|
||||||
AccountStatusesListView(mode: .bookmarks)
|
AccountStatusesListView(mode: .bookmarks)
|
||||||
|
@ -67,8 +69,10 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
NavigationTab {
|
NavigationTab {
|
||||||
ListsListView()
|
ListsListView()
|
||||||
}
|
}
|
||||||
|
case .links:
|
||||||
|
NavigationTab { TrendingLinksListView(cards: []) }
|
||||||
case .post:
|
case .post:
|
||||||
VStack { }
|
VStack {}
|
||||||
case .other:
|
case .other:
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
|
@ -76,40 +80,47 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var label: some View {
|
var label: some View {
|
||||||
|
if self != .other {
|
||||||
|
Label(title, systemImage: iconName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var title: LocalizedStringKey {
|
||||||
switch self {
|
switch self {
|
||||||
case .timeline:
|
case .timeline:
|
||||||
Label("tab.timeline", systemImage: iconName)
|
"tab.timeline"
|
||||||
case .trending:
|
case .trending:
|
||||||
Label("tab.trending", systemImage: iconName)
|
"tab.trending"
|
||||||
case .local:
|
case .local:
|
||||||
Label("tab.local", systemImage: iconName)
|
"tab.local"
|
||||||
case .federated:
|
case .federated:
|
||||||
Label("tab.federated", systemImage: iconName)
|
"tab.federated"
|
||||||
case .notifications:
|
case .notifications:
|
||||||
Label("tab.notifications", systemImage: iconName)
|
"tab.notifications"
|
||||||
case .mentions:
|
case .mentions:
|
||||||
Label("tab.mentions", systemImage: iconName)
|
"tab.mentions"
|
||||||
case .explore:
|
case .explore:
|
||||||
Label("tab.explore", systemImage: iconName)
|
"tab.explore"
|
||||||
case .messages:
|
case .messages:
|
||||||
Label("tab.messages", systemImage: iconName)
|
"tab.messages"
|
||||||
case .settings:
|
case .settings:
|
||||||
Label("tab.settings", systemImage: iconName)
|
"tab.settings"
|
||||||
case .profile:
|
case .profile:
|
||||||
Label("tab.profile", systemImage: iconName)
|
"tab.profile"
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
Label("accessibility.tabs.profile.picker.bookmarks", systemImage: iconName)
|
"accessibility.tabs.profile.picker.bookmarks"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
Label("accessibility.tabs.profile.picker.favorites", systemImage: iconName)
|
"accessibility.tabs.profile.picker.favorites"
|
||||||
case .post:
|
case .post:
|
||||||
Label("menu.new-post", systemImage: iconName)
|
"menu.new-post"
|
||||||
case .followedTags:
|
case .followedTags:
|
||||||
Label("timeline.filter.tags", systemImage: iconName)
|
"timeline.filter.tags"
|
||||||
case .lists:
|
case .lists:
|
||||||
Label("timeline.filter.lists", systemImage: iconName)
|
"timeline.filter.lists"
|
||||||
|
case .links:
|
||||||
|
"explore.section.trending.links"
|
||||||
case .other:
|
case .other:
|
||||||
EmptyView()
|
""
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,16 +156,19 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
"tag"
|
"tag"
|
||||||
case .lists:
|
case .lists:
|
||||||
"list.bullet"
|
"list.bullet"
|
||||||
|
case .links:
|
||||||
|
"newspaper"
|
||||||
case .other:
|
case .other:
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
@Observable
|
@Observable
|
||||||
class SidebarTabs {
|
class SidebarTabs {
|
||||||
struct SidedebarTab: Hashable, Codable {
|
struct SidedebarTab: Hashable, Codable {
|
||||||
let tab: Tab
|
let tab: AppTab
|
||||||
var enabled: Bool
|
var enabled: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,6 +186,7 @@ class SidebarTabs {
|
||||||
.init(tab: .favorites, enabled: true),
|
.init(tab: .favorites, enabled: true),
|
||||||
.init(tab: .followedTags, enabled: true),
|
.init(tab: .followedTags, enabled: true),
|
||||||
.init(tab: .lists, enabled: true),
|
.init(tab: .lists, enabled: true),
|
||||||
|
.init(tab: .links, enabled: true),
|
||||||
|
|
||||||
.init(tab: .settings, enabled: true),
|
.init(tab: .settings, enabled: true),
|
||||||
.init(tab: .profile, enabled: true),
|
.init(tab: .profile, enabled: true),
|
||||||
|
@ -187,7 +202,7 @@ class SidebarTabs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEnabled(_ tab: Tab) -> Bool {
|
func isEnabled(_ tab: AppTab) -> Bool {
|
||||||
tabs.first(where: { $0.tab.id == tab.id })?.enabled == true
|
tabs.first(where: { $0.tab.id == tab.id })?.enabled == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +211,7 @@ class SidebarTabs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
@Observable
|
@Observable
|
||||||
class iOSTabs {
|
class iOSTabs {
|
||||||
enum TabEntries: String {
|
enum TabEntries: String {
|
||||||
|
@ -203,45 +219,45 @@ class iOSTabs {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Storage {
|
class Storage {
|
||||||
@AppStorage(TabEntries.first.rawValue) var firstTab = Tab.timeline
|
@AppStorage(TabEntries.first.rawValue) var firstTab = AppTab.timeline
|
||||||
@AppStorage(TabEntries.second.rawValue) var secondTab = Tab.notifications
|
@AppStorage(TabEntries.second.rawValue) var secondTab = AppTab.notifications
|
||||||
@AppStorage(TabEntries.third.rawValue) var thirdTab = Tab.explore
|
@AppStorage(TabEntries.third.rawValue) var thirdTab = AppTab.explore
|
||||||
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = Tab.messages
|
@AppStorage(TabEntries.fourth.rawValue) var fourthTab = AppTab.links
|
||||||
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = Tab.profile
|
@AppStorage(TabEntries.fifth.rawValue) var fifthTab = AppTab.profile
|
||||||
}
|
}
|
||||||
|
|
||||||
private let storage = Storage()
|
private let storage = Storage()
|
||||||
public static let shared = iOSTabs()
|
public static let shared = iOSTabs()
|
||||||
|
|
||||||
var tabs: [Tab] {
|
var tabs: [AppTab] {
|
||||||
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
[firstTab, secondTab, thirdTab, fourthTab, fifthTab]
|
||||||
}
|
}
|
||||||
|
|
||||||
var firstTab: Tab {
|
var firstTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.firstTab = firstTab
|
storage.firstTab = firstTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var secondTab: Tab {
|
var secondTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.secondTab = secondTab
|
storage.secondTab = secondTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var thirdTab: Tab {
|
var thirdTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.thirdTab = thirdTab
|
storage.thirdTab = thirdTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fourthTab: Tab {
|
var fourthTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.fourthTab = fourthTab
|
storage.fourthTab = fourthTab
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var fifthTab: Tab {
|
var fifthTab: AppTab {
|
||||||
didSet {
|
didSet {
|
||||||
storage.fifthTab = fifthTab
|
storage.fifthTab = fifthTab
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import Models
|
||||||
import Network
|
import Network
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import SFSafeSymbols
|
import SFSafeSymbols
|
||||||
import Shimmer
|
|
||||||
import SwiftData
|
import SwiftData
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
@ -39,7 +38,9 @@ struct EditTagGroupView: View {
|
||||||
focusedField: $focusedField
|
focusedField: $focusedField
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
|
|
||||||
Section("add-tag-groups.edit.tags") {
|
Section("add-tag-groups.edit.tags") {
|
||||||
TagsInputView(
|
TagsInputView(
|
||||||
|
@ -48,7 +49,9 @@ struct EditTagGroupView: View {
|
||||||
focusedField: $focusedField
|
focusedField: $focusedField
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
.formStyle(.grouped)
|
.formStyle(.grouped)
|
||||||
.navigationTitle(
|
.navigationTitle(
|
||||||
|
@ -58,22 +61,20 @@ struct EditTagGroupView: View {
|
||||||
)
|
)
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
.scrollDismissesKeyboard(.interactively)
|
.scrollDismissesKeyboard(.interactively)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
CancelToolbarItem()
|
||||||
Button("action.cancel", action: { dismiss() })
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
|
Button("action.save", action: { save() })
|
||||||
|
.disabled(!tagGroup.isValid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
.onAppear {
|
||||||
Button("action.save", action: { save() })
|
focusedField = .title
|
||||||
.disabled(!tagGroup.isValid)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.onAppear {
|
|
||||||
focusedField = .title
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import Env
|
||||||
import Models
|
import Models
|
||||||
import Network
|
import Network
|
||||||
import NukeUI
|
import NukeUI
|
||||||
import Shimmer
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@ -38,6 +37,11 @@ struct AddRemoteTimelineView: View {
|
||||||
.foregroundColor(.green)
|
.foregroundColor(.green)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
}
|
}
|
||||||
|
if !instanceName.isEmpty && instance == nil {
|
||||||
|
Label("timeline.\(instanceName)-not-valid", systemImage: "xmark.seal.fill")
|
||||||
|
.foregroundColor(.red)
|
||||||
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
}
|
||||||
Button {
|
Button {
|
||||||
guard instance != nil else { return }
|
guard instance != nil else { return }
|
||||||
context.insert(LocalTimeline(instance: instanceName))
|
context.insert(LocalTimeline(instance: instanceName))
|
||||||
|
@ -46,6 +50,7 @@ struct AddRemoteTimelineView: View {
|
||||||
Text("timeline.add.action.add")
|
Text("timeline.add.action.add")
|
||||||
}
|
}
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
|
.disabled(instance == nil)
|
||||||
|
|
||||||
instancesListView
|
instancesListView
|
||||||
}
|
}
|
||||||
|
@ -53,31 +58,30 @@ struct AddRemoteTimelineView: View {
|
||||||
.navigationTitle("timeline.add-remote.title")
|
.navigationTitle("timeline.add-remote.title")
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollContentBackground(.hidden)
|
.scrollContentBackground(.hidden)
|
||||||
.background(theme.secondaryBackgroundColor)
|
.background(theme.secondaryBackgroundColor)
|
||||||
.scrollDismissesKeyboard(.immediately)
|
.scrollDismissesKeyboard(.immediately)
|
||||||
#endif
|
#endif
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
CancelToolbarItem()
|
||||||
Button("action.cancel", action: { dismiss() })
|
|
||||||
}
|
}
|
||||||
}
|
.onChange(of: instanceName) { _, newValue in
|
||||||
.onChange(of: instanceName) { _, newValue in
|
instanceNamePublisher.send(newValue)
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
.onReceive(instanceNamePublisher.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)) { newValue in
|
||||||
.onAppear {
|
Task {
|
||||||
isInstanceURLFieldFocused = true
|
let client = Client(server: newValue)
|
||||||
let client = InstanceSocialClient()
|
instance = try? await client.get(endpoint: Instances.instance)
|
||||||
Task {
|
}
|
||||||
instances = await client.fetchInstances(keyword: instanceName)
|
}
|
||||||
|
.onAppear {
|
||||||
|
isInstanceURLFieldFocused = true
|
||||||
|
let client = InstanceSocialClient()
|
||||||
|
let instanceName = instanceName
|
||||||
|
Task {
|
||||||
|
instances = await client.fetchInstances(keyword: instanceName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,10 @@ struct TimelineTab: View {
|
||||||
@Environment(UserPreferences.self) private var preferences
|
@Environment(UserPreferences.self) private var preferences
|
||||||
@Environment(Client.self) private var client
|
@Environment(Client.self) private var client
|
||||||
@State private var routerPath = RouterPath()
|
@State private var routerPath = RouterPath()
|
||||||
@Binding var popToRootTab: Tab
|
|
||||||
|
|
||||||
@State private var didAppear: Bool = false
|
@State private var didAppear: Bool = false
|
||||||
@State private var timeline: TimelineFilter = .home
|
@State private var timeline: TimelineFilter = .home
|
||||||
@State private var selectedTagGroup: TagGroup?
|
@State private var selectedTagGroup: TagGroup?
|
||||||
@State private var scrollToTopSignal: Int = 0
|
|
||||||
|
|
||||||
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
|
@Query(sort: \LocalTimeline.creationDate, order: .reverse) var localTimelines: [LocalTimeline]
|
||||||
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
@Query(sort: \TagGroup.creationDate, order: .reverse) var tagGroups: [TagGroup]
|
||||||
|
@ -33,9 +31,8 @@ struct TimelineTab: View {
|
||||||
|
|
||||||
private let canFilterTimeline: Bool
|
private let canFilterTimeline: Bool
|
||||||
|
|
||||||
init(popToRootTab: Binding<Tab>, timeline: TimelineFilter? = nil) {
|
init(timeline: TimelineFilter? = nil) {
|
||||||
canFilterTimeline = timeline == nil
|
canFilterTimeline = timeline == nil
|
||||||
_popToRootTab = popToRootTab
|
|
||||||
_timeline = .init(initialValue: timeline ?? .home)
|
_timeline = .init(initialValue: timeline ?? .home)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,14 +41,13 @@ struct TimelineTab: View {
|
||||||
TimelineView(timeline: $timeline,
|
TimelineView(timeline: $timeline,
|
||||||
pinnedFilters: $pinnedFilters,
|
pinnedFilters: $pinnedFilters,
|
||||||
selectedTagGroup: $selectedTagGroup,
|
selectedTagGroup: $selectedTagGroup,
|
||||||
scrollToTopSignal: $scrollToTopSignal,
|
|
||||||
canFilterTimeline: canFilterTimeline)
|
canFilterTimeline: canFilterTimeline)
|
||||||
.withAppRouter()
|
.withAppRouter()
|
||||||
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $routerPath.presentedSheet)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
toolbarView
|
toolbarView
|
||||||
}
|
}
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.50), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
.id(client.id)
|
.id(client.id)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
|
@ -61,31 +57,22 @@ struct TimelineTab: View {
|
||||||
if client.isAuth {
|
if client.isAuth {
|
||||||
timeline = lastTimelineFilter
|
timeline = lastTimelineFilter
|
||||||
} else {
|
} else {
|
||||||
timeline = .federated
|
timeline = .trending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task {
|
|
||||||
await currentAccount.fetchLists()
|
|
||||||
}
|
|
||||||
if !client.isAuth {
|
if !client.isAuth {
|
||||||
routerPath.presentedSheet = .addAccount
|
routerPath.presentedSheet = .addAccount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.task {
|
||||||
|
await currentAccount.fetchLists()
|
||||||
|
}
|
||||||
.onChange(of: client.isAuth) {
|
.onChange(of: client.isAuth) {
|
||||||
resetTimelineFilter()
|
resetTimelineFilter()
|
||||||
}
|
}
|
||||||
.onChange(of: currentAccount.account?.id) {
|
.onChange(of: currentAccount.account?.id) {
|
||||||
resetTimelineFilter()
|
resetTimelineFilter()
|
||||||
}
|
}
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .timeline {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: client.id) {
|
.onChange(of: client.id) {
|
||||||
routerPath.path = []
|
routerPath.path = []
|
||||||
}
|
}
|
||||||
|
@ -95,7 +82,7 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
switch newValue {
|
switch newValue {
|
||||||
case let .tagGroup(title, _, _):
|
case let .tagGroup(title, _, _):
|
||||||
if let group = tagGroups.first(where: { $0.title == title}) {
|
if let group = tagGroups.first(where: { $0.title == title }) {
|
||||||
selectedTagGroup = group
|
selectedTagGroup = group
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -123,16 +110,16 @@ struct TimelineTab: View {
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var timelineFilterButton: some View {
|
private var timelineFilterButton: some View {
|
||||||
latestOrResumeButtons
|
headerGroup
|
||||||
contentFilterButton
|
|
||||||
Divider()
|
|
||||||
pinMenuButton
|
|
||||||
Divider()
|
|
||||||
timelineFiltersButtons
|
timelineFiltersButtons
|
||||||
listsFiltersButons
|
if client.isAuth {
|
||||||
tagsFiltersButtons
|
listsFiltersButons
|
||||||
|
tagsFiltersButtons
|
||||||
|
}
|
||||||
localTimelinesFiltersButtons
|
localTimelinesFiltersButtons
|
||||||
tagGroupsFiltersButtons
|
tagGroupsFiltersButtons
|
||||||
|
Divider()
|
||||||
|
contentFilterButton
|
||||||
}
|
}
|
||||||
|
|
||||||
private var addAccountButton: some View {
|
private var addAccountButton: some View {
|
||||||
|
@ -189,12 +176,14 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var latestOrResumeButtons: some View {
|
private var headerGroup: some View {
|
||||||
if timeline.supportNewestPagination {
|
ControlGroup {
|
||||||
Button {
|
if timeline.supportNewestPagination {
|
||||||
timeline = .latest
|
Button {
|
||||||
} label: {
|
timeline = .latest
|
||||||
Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName())
|
} label: {
|
||||||
|
Label(TimelineFilter.latest.localizedTitle(), systemImage: TimelineFilter.latest.iconName())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if timeline == .home {
|
if timeline == .home {
|
||||||
Button {
|
Button {
|
||||||
|
@ -206,22 +195,25 @@ struct TimelineTab: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pinButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var pinMenuButton: some View {
|
private var pinButton: some View {
|
||||||
let index = pinnedFilters.firstIndex(where: { $0.id == timeline.id})
|
let index = pinnedFilters.firstIndex(where: { $0.id == timeline.id })
|
||||||
Button {
|
Button {
|
||||||
withAnimation {
|
withAnimation {
|
||||||
if let index {
|
if let index {
|
||||||
pinnedFilters.remove(at: index)
|
let timeline = pinnedFilters.remove(at: index)
|
||||||
|
Telemetry.signal("timeline.pin.removed", parameters: ["timeline" : timeline.rawValue])
|
||||||
} else {
|
} else {
|
||||||
pinnedFilters.append(timeline)
|
pinnedFilters.append(timeline)
|
||||||
|
Telemetry.signal("timeline.pin.added", parameters: ["timeline" : timeline.rawValue])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
if index != nil {
|
if index != nil {
|
||||||
Label("status.action.unpin", systemImage: "pin.slash")
|
Label("status.action.unpin", systemImage: "pin.slash")
|
||||||
} else {
|
} else {
|
||||||
Label("status.action.pin", systemImage: "pin")
|
Label("status.action.pin", systemImage: "pin")
|
||||||
|
@ -324,7 +316,7 @@ struct TimelineTab: View {
|
||||||
if client.isAuth, canFilterTimeline {
|
if client.isAuth, canFilterTimeline {
|
||||||
timeline = lastTimelineFilter
|
timeline = lastTimelineFilter
|
||||||
} else if !client.isAuth {
|
} else if !client.isAuth {
|
||||||
timeline = .federated
|
timeline = .trending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import SwiftUI
|
|
||||||
import Env
|
|
||||||
import AppAccount
|
import AppAccount
|
||||||
import DesignSystem
|
import DesignSystem
|
||||||
|
import Env
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct ToolbarTab: ToolbarContent {
|
struct ToolbarTab: ToolbarContent {
|
||||||
|
@ -9,17 +9,36 @@ struct ToolbarTab: ToolbarContent {
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
|
|
||||||
@Environment(UserPreferences.self) private var userPreferences
|
@Environment(UserPreferences.self) private var userPreferences
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
@Binding var routerPath: RouterPath
|
@Binding var routerPath: RouterPath
|
||||||
|
|
||||||
var body: some ToolbarContent {
|
var body: some ToolbarContent {
|
||||||
if !isSecondaryColumn {
|
if !isSecondaryColumn {
|
||||||
|
if horizontalSizeClass == .regular {
|
||||||
|
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,
|
statusEditorToolbarItem(routerPath: routerPath,
|
||||||
visibility: userPreferences.postVisibility)
|
visibility: userPreferences.postVisibility)
|
||||||
if UIDevice.current.userInterfaceIdiom != .pad ||
|
if UIDevice.current.userInterfaceIdiom != .pad ||
|
||||||
(UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact) {
|
(UIDevice.current.userInterfaceIdiom == .pad && horizontalSizeClass == .compact)
|
||||||
|
{
|
||||||
ToolbarItem(placement: .navigationBarLeading) {
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
AppAccountsSelectorView(routerPath: routerPath)
|
AppAccountsSelectorView(routerPath: routerPath, avatarConfig: theme.avatarShape == .circle ? .badge : .badgeRounded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/128.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/16.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/256 1.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/256.png
Normal file
After Width: | Height: | Size: 47 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/32 1.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/32.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/512 1.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/512.png
Normal file
After Width: | Height: | Size: 147 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/64.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 156 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/Content.png
Normal file
After Width: | Height: | Size: 501 KiB |
|
@ -1,67 +1,91 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "AppIcon.png",
|
"filename" : "AppIcon-fs8.png",
|
||||||
"idiom" : "universal",
|
"idiom" : "universal",
|
||||||
"platform" : "ios",
|
"platform" : "ios",
|
||||||
"size" : "1024x1024"
|
"size" : "1024x1024"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-16.png",
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "dark.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "tinted"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"filename" : "tinted.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "16.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-32.png",
|
"filename" : "32.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "16x16"
|
"size" : "16x16"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-32 1.png",
|
"filename" : "32 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-64.png",
|
"filename" : "64.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "32x32"
|
"size" : "32x32"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-128.png",
|
"filename" : "128.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-256 1.png",
|
"filename" : "256 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "128x128"
|
"size" : "128x128"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-256.png",
|
"filename" : "256.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-512 1.png",
|
"filename" : "512 1.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "256x256"
|
"size" : "256x256"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-512.png",
|
"filename" : "512.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "1x",
|
"scale" : "1x",
|
||||||
"size" : "512x512"
|
"size" : "512x512"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"filename" : "Icon-1024.png",
|
"filename" : "Content.png",
|
||||||
"idiom" : "mac",
|
"idiom" : "mac",
|
||||||
"scale" : "2x",
|
"scale" : "2x",
|
||||||
"size" : "512x512"
|
"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/dark.png
Normal file
After Width: | Height: | Size: 370 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIcon.appiconset/tinted.png
Normal file
After Width: | Height: | Size: 545 KiB |
Before Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 764 KiB |
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "Back.png",
|
"filename" : "Background.png",
|
||||||
"idiom" : "vision",
|
"idiom" : "vision",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "Front.png",
|
"filename" : "Layer 1.png",
|
||||||
"idiom" : "vision",
|
"idiom" : "vision",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 543 KiB |
After Width: | Height: | Size: 549 KiB |
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"filename" : "Middle.png",
|
|
||||||
"idiom" : "vision",
|
"idiom" : "vision",
|
||||||
"scale" : "2x"
|
"scale" : "2x"
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 78 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate0-image.imageset/AppIcon-fs8.png
vendored
Normal file
After Width: | Height: | Size: 79 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate0-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIcon-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate1-image.imageset/1024.png
vendored
Normal file
After Width: | Height: | Size: 85 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate1-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "1024.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate10-image.imageset/AppIconAlternate10.png
vendored
Normal file
After Width: | Height: | Size: 151 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate10-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIconAlternate10.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate11-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon15.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate11-image.imageset/icon15.png
vendored
Normal file
After Width: | Height: | Size: 120 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate12-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon16.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate12-image.imageset/icon16.png
vendored
Normal file
After Width: | Height: | Size: 108 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate13-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon17.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate13-image.imageset/icon17.png
vendored
Normal file
After Width: | Height: | Size: 72 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate14-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon18.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate14-image.imageset/icon18.png
vendored
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate15-image.imageset/AppIconAlternate15.png
vendored
Normal file
After Width: | Height: | Size: 91 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate15-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIconAlternate15.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate16-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate16-image.imageset/icon.png
vendored
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate17-image.imageset/Alternate43-fs8.png
vendored
Normal file
After Width: | Height: | Size: 102 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate17-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate43-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate18-image.imageset/Alternate44-fs8.png
vendored
Normal file
After Width: | Height: | Size: 165 KiB |