Full Xcode 16 supports + iOS 18 support (#2100)
* Compile on iOS 18
* Fix more warnings
* Tweak build settings
* Migrate to Swift Tests
* better tests
* Fix
* Fix tests
* More TabView cleanup
Bump to iOS 18 only + remove custom sidebar
* Revert "More TabView cleanup"
This reverts commit e051437fcb
.
* Tabbar fix + bump to iOS 18
* Remove popToRoot
* Cleanup scrollToTop
* Support both TapBar
* Better TabView support
* Better TabView support
* Cleanup
* Disable TabView animations
* Remove id in ForEach
* Remove external init for StatusRowView
* Cleanup
* More Swift 6 concurrency
* Swift 6 mode
* Fixes
* Full Swift 6 packages support
* For now compile env in Swift 5 mode
* Fix archive
* More fix to Archive
* Address `dispatch_assert_queue_fail` (#2161)
See https://twitter.com/dimillian/status/1823089444397724003?s=61&t=SC3rvyJQWn1NQqAgMVrT0Q
* Bump Env to Swift 6
* Fix push notification
* Remove unecessary workaround
* Cleanup
* Move to @Entry
* Fix TabView on Catalyst
* Fix build
* Fix build 2
* fix warning
* Fix icons for iOS 18
---------
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
|
@ -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 {
|
||||||
|
|
|
@ -1211,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;
|
||||||
|
@ -1246,7 +1246,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";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
};
|
};
|
||||||
|
@ -1269,7 +1269,7 @@
|
||||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1283,7 +1283,7 @@
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
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;
|
||||||
|
@ -1305,7 +1305,7 @@
|
||||||
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
INFOPLIST_FILE = IceCubesAppWidgetsExtension/Info.plist;
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
INFOPLIST_KEY_CFBundleDisplayName = IceCubesAppWidgetsExtension;
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
|
@ -1318,7 +1318,7 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
@ -1353,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;
|
||||||
|
@ -1387,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;
|
||||||
};
|
};
|
||||||
|
@ -1456,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;
|
||||||
};
|
};
|
||||||
|
@ -1515,6 +1516,7 @@
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
@ -1569,8 +1571,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 = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -1625,8 +1638,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;
|
||||||
};
|
};
|
||||||
|
@ -1660,7 +1684,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;
|
||||||
|
@ -1695,7 +1719,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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -19,9 +19,9 @@ 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):
|
case let .accountMediaGridView(account, initialMedia):
|
||||||
|
@ -38,19 +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)
|
canFilterTimeline: false)
|
||||||
case let .linkTimeline(url, title):
|
case let .linkTimeline(url, title):
|
||||||
TimelineView(timeline: .constant(.link(url: url, title: title)),
|
TimelineView(timeline: .constant(.link(url: url, title: title)),
|
||||||
pinnedFilters: .constant([]),
|
pinnedFilters: .constant([]),
|
||||||
selectedTagGroup: .constant(nil),
|
selectedTagGroup: .constant(nil),
|
||||||
scrollToTopSignal: .constant(0),
|
|
||||||
canFilterTimeline: false)
|
canFilterTimeline: false)
|
||||||
case let .following(id):
|
case let .following(id):
|
||||||
AccountsListView(mode: .following(accountId: id))
|
AccountsListView(mode: .following(accountId: id))
|
||||||
|
@ -66,7 +63,6 @@ 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):
|
||||||
TrendingLinksListView(cards: cards)
|
TrendingLinksListView(cards: cards)
|
||||||
|
@ -76,8 +72,7 @@ extension View {
|
||||||
NotificationsRequestsListView()
|
NotificationsRequestsListView()
|
||||||
case let .notificationForAccount(accountId):
|
case let .notificationForAccount(accountId):
|
||||||
NotificationsListView(lockedType: nil,
|
NotificationsListView(lockedType: nil,
|
||||||
lockedAccountId: accountId,
|
lockedAccountId: accountId)
|
||||||
scrollToTopSignal: .constant(0))
|
|
||||||
case .blockedAccounts:
|
case .blockedAccounts:
|
||||||
AccountsListView(mode: .blocked)
|
AccountsListView(mode: .blocked)
|
||||||
case .mutedAccounts:
|
case .mutedAccounts:
|
||||||
|
@ -135,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:
|
||||||
|
@ -236,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
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,9 @@ struct AppView: View {
|
||||||
@Environment(\.openWindow) var openWindow
|
@Environment(\.openWindow) var openWindow
|
||||||
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
@Environment(\.horizontalSizeClass) private var horizontalSizeClass
|
||||||
|
|
||||||
@Binding var selectedTab: Tab
|
@Binding var selectedTab: AppTab
|
||||||
@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
|
||||||
|
|
||||||
|
@ -40,45 +39,27 @@ struct AppView: View {
|
||||||
#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)
|
||||||
#if os(visionOS)
|
|
||||||
openWindow(value: WindowDestinationEditor.newStatusEditor(visibility: userPreferences.postVisibility))
|
|
||||||
#else
|
|
||||||
appRouterPath.presentedSheet = .newStatusEditor(visibility: userPreferences.postVisibility)
|
|
||||||
#endif
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if newTab == selectedTab {
|
|
||||||
/// Stupid hack to trigger onChange binding in tab views.
|
|
||||||
popToRootTab = .other
|
|
||||||
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
|
||||||
|
@ -95,8 +76,24 @@ struct AppView: View {
|
||||||
.id(appAccountsManager.currentClient.id)
|
.id(appAccountsManager.currentClient.id)
|
||||||
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
.withSheetDestinations(sheetDestinations: $appRouterPath.presentedSheet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
private func badgeFor(tab: Tab) -> Int {
|
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
|
||||||
{
|
{
|
||||||
|
@ -108,25 +105,17 @@ struct AppView: View {
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
var sidebarView: some View {
|
var sidebarView: some View {
|
||||||
SideBarView(selectedTab: $selectedTab,
|
SideBarView(selectedTab: $selectedTab,
|
||||||
popToRootTab: $popToRootTab,
|
|
||||||
tabs: availableTabs)
|
tabs: availableTabs)
|
||||||
{
|
{
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
TabView(selection: $selectedTab) {
|
if #available(iOS 18.0, *) {
|
||||||
ForEach(availableTabs) { tab in
|
baseTabView
|
||||||
tab
|
.tabViewStyle(.sidebarAdaptable)
|
||||||
.makeContentView(selectedTab: $selectedTab, popToRootTab: $popToRootTab)
|
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
||||||
.tabItem {
|
tabview.sidebar.isHidden = true
|
||||||
tab.label
|
|
||||||
}
|
|
||||||
.tag(tab)
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
.id(availableTabs.count) /// Resets the TabView state when the number of tabs changes to avoid navigation bar issues and prevent crashes
|
baseTabView
|
||||||
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
|
||||||
tabview.tabBar.isHidden = horizontalSizeClass == .regular
|
|
||||||
tabview.customizableViewControllers = []
|
|
||||||
tabview.moreNavigationController.isNavigationBarHidden = true
|
|
||||||
}
|
}
|
||||||
if horizontalSizeClass == .regular,
|
if horizontalSizeClass == .regular,
|
||||||
appAccountsManager.currentClient.isAuth,
|
appAccountsManager.currentClient.isAuth,
|
||||||
|
@ -140,10 +129,30 @@ struct AppView: View {
|
||||||
.environment(appRouterPath)
|
.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.id(availableTabs.count) /// Resets the TabView state when the number of tabs changes to avoid navigation bar issues and prevent crashes
|
||||||
|
.introspect(.tabView, on: .iOS(.v17, .v18)) { (tabview: UITabBarController) in
|
||||||
|
tabview.tabBar.isHidden = horizontalSizeClass == .regular
|
||||||
|
tabview.customizableViewControllers = []
|
||||||
|
tabview.moreNavigationController.isNavigationBarHidden = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
|
@ -29,7 +29,7 @@ struct IceCubesApp: App {
|
||||||
@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
|
||||||
|
|
|
@ -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,7 +33,7 @@ struct SideBarView<Content: View>: View {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeIconForTab(tab: Tab) -> some View {
|
private func makeIconForTab(tab: AppTab) -> some View {
|
||||||
HStack {
|
HStack {
|
||||||
ZStack(alignment: .topTrailing) {
|
ZStack(alignment: .topTrailing) {
|
||||||
SideBarIcon(systemIconName: tab.iconName,
|
SideBarIcon(systemIconName: tab.iconName,
|
||||||
|
@ -89,7 +88,7 @@ struct SideBarView<Content: View>: View {
|
||||||
.offset(x: 2, y: -2)
|
.offset(x: 2, y: -2)
|
||||||
}
|
}
|
||||||
.buttonStyle(.borderedProminent)
|
.buttonStyle(.borderedProminent)
|
||||||
.help(Tab.post.title)
|
.help(AppTab.post.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
private func makeAccountButton(account: AppAccount, showBadge: Bool) -> some View {
|
||||||
|
@ -139,7 +138,7 @@ struct SideBarView<Content: View>: View {
|
||||||
if let accountName {
|
if let accountName {
|
||||||
"tab.profile-account-\(accountName)"
|
"tab.profile-account-\(accountName)"
|
||||||
} else {
|
} else {
|
||||||
Tab.profile.title
|
AppTab.profile.title
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,13 +148,6 @@ struct SideBarView<Content: View>: View {
|
||||||
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 {
|
||||||
|
|
|
@ -13,12 +13,10 @@ 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.30), for: .navigationBar)
|
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), for: .navigationBar)
|
||||||
|
@ -28,15 +26,6 @@ struct ExploreTab: View {
|
||||||
}
|
}
|
||||||
.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 = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,12 +15,10 @@ 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 {
|
||||||
|
@ -29,15 +27,6 @@ struct MessagesTab: View {
|
||||||
.toolbarBackground(theme.primaryBackgroundColor.opacity(0.30), 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 = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
@ -51,15 +49,6 @@ struct NotificationsTab: View {
|
||||||
}
|
}
|
||||||
.withSafariRouter()
|
.withSafariRouter()
|
||||||
.environment(routerPath)
|
.environment(routerPath)
|
||||||
.onChange(of: $popToRootTab.wrappedValue) { _, newValue in
|
|
||||||
if newValue == .notifications {
|
|
||||||
if routerPath.path.isEmpty {
|
|
||||||
scrollToTopSignal += 1
|
|
||||||
} else {
|
|
||||||
routerPath.path = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.onChange(of: selectedTab) { _, _ in
|
.onChange(of: selectedTab) { _, _ in
|
||||||
clearNotifications()
|
clearNotifications()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,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.30), 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 = []
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,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
|
||||||
}
|
}
|
||||||
|
@ -166,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)
|
||||||
|
|
|
@ -92,6 +92,7 @@ struct AddAccountView: View {
|
||||||
}
|
}
|
||||||
.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 {
|
||||||
|
@ -102,6 +103,8 @@ struct AddAccountView: View {
|
||||||
}
|
}
|
||||||
.onChange(of: instanceName) {
|
.onChange(of: instanceName) {
|
||||||
searchingTask.cancel()
|
searchingTask.cancel()
|
||||||
|
let instanceName = instanceName
|
||||||
|
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 }
|
||||||
|
@ -127,7 +130,7 @@ struct AddAccountView: View {
|
||||||
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
|
instanceFetchError = nil
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -33,6 +33,10 @@ struct IconSelectorView: View {
|
||||||
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 {
|
||||||
|
@ -98,7 +102,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)
|
||||||
|
|
|
@ -28,8 +28,6 @@ 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
|
@State private var startingPoint: SettingsStartingPoint? = nil
|
||||||
|
@ -103,11 +101,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 {
|
||||||
|
@ -265,7 +258,7 @@ 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")
|
||||||
if let image: UIImage = .init(named: icon.appIconName) {
|
if let image: UIImage = .init(named: icon.previewImageName) {
|
||||||
Image(uiImage: image)
|
Image(uiImage: image)
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 25, height: 25)
|
.frame(width: 25, height: 25)
|
||||||
|
|
|
@ -14,35 +14,35 @@ 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
|
||||||
if tab == tabs.firstTab || !tabs.tabs.contains(tab) {
|
if tab == tabs.firstTab || !tabs.tabs.contains(tab) {
|
||||||
tab.label.tag(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
|
||||||
if tab == tabs.secondTab || !tabs.tabs.contains(tab) {
|
if tab == tabs.secondTab || !tabs.tabs.contains(tab) {
|
||||||
tab.label.tag(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
|
||||||
if tab == tabs.thirdTab || !tabs.tabs.contains(tab) {
|
if tab == tabs.thirdTab || !tabs.tabs.contains(tab) {
|
||||||
tab.label.tag(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
|
||||||
if tab == tabs.fourthTab || !tabs.tabs.contains(tab) {
|
if tab == tabs.fourthTab || !tabs.tabs.contains(tab) {
|
||||||
tab.label.tag(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
|
||||||
if tab == tabs.fifthTab || !tabs.tabs.contains(tab) {
|
if tab == tabs.fifthTab || !tabs.tabs.contains(tab) {
|
||||||
tab.label.tag(tab)
|
tab.label.tag(tab)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,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
|
||||||
|
@ -22,37 +22,37 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
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, .post, .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)
|
||||||
|
@ -168,7 +168,7 @@ enum Tab: Int, Identifiable, Hashable, CaseIterable, Codable {
|
||||||
@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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,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.links
|
@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
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ struct AddRemoteTimelineView: View {
|
||||||
.onAppear {
|
.onAppear {
|
||||||
isInstanceURLFieldFocused = true
|
isInstanceURLFieldFocused = true
|
||||||
let client = InstanceSocialClient()
|
let client = InstanceSocialClient()
|
||||||
|
let instanceName = instanceName
|
||||||
Task {
|
Task {
|
||||||
instances = await client.fetchInstances(keyword: instanceName)
|
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,7 +41,6 @@ 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)
|
||||||
|
@ -77,15 +73,6 @@ struct TimelineTab: View {
|
||||||
.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 = []
|
||||||
}
|
}
|
||||||
|
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate0-image.imageset/1024.png
vendored
Normal file
After Width: | Height: | Size: 102 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate0-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/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 |
21
IceCubesApp/Assets.xcassets/AppIconAlternate18-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate44-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate19-image.imageset/Alternate45-fs8.png
vendored
Normal file
After Width: | Height: | Size: 172 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate19-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate45-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate2-image.imageset/AppIconAlternate2.png
vendored
Normal file
After Width: | Height: | Size: 96 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate2-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIconAlternate2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate20-image.imageset/Alternate46-fs8.png
vendored
Normal file
After Width: | Height: | Size: 174 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate20-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate46-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate21-image.imageset/Alternate47-fs8.png
vendored
Normal file
After Width: | Height: | Size: 189 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate21-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate47-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate22-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon23.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate22-image.imageset/icon23.png
vendored
Normal file
After Width: | Height: | Size: 34 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate23-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon24.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate23-image.imageset/icon24.png
vendored
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate24-image.imageset/AppIconAlternate21.png
vendored
Normal file
After Width: | Height: | Size: 123 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate24-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIconAlternate21.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate25-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon22.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate25-image.imageset/icon22.png
vendored
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate26-image.imageset/AppIconAlternate20.png
vendored
Normal file
After Width: | Height: | Size: 117 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate26-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "AppIconAlternate20.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate27-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icecubes_comic_01.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate27-image.imageset/icecubes_comic_01.png
vendored
Normal file
After Width: | Height: | Size: 33 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate28-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icecubes_comic_02.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate28-image.imageset/icecubes_comic_02.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate29-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icecubes_comic_03.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate29-image.imageset/icecubes_comic_03.png
vendored
Normal file
After Width: | Height: | Size: 41 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate3-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon6.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate3-image.imageset/icon6.png
vendored
Normal file
After Width: | Height: | Size: 113 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate30-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "blue.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate30-image.imageset/blue.png
vendored
Normal file
After Width: | Height: | Size: 54 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate31-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "purple_alt.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate31-image.imageset/purple_alt.png
vendored
Normal file
After Width: | Height: | Size: 24 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate32-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "purple.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate32-image.imageset/purple.png
vendored
Normal file
After Width: | Height: | Size: 48 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate33-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "stripe.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate33-image.imageset/stripe.png
vendored
Normal file
After Width: | Height: | Size: 35 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate34-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "blue_alt2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate34-image.imageset/blue_alt2.png
vendored
Normal file
After Width: | Height: | Size: 58 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate35-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "purple_alt2.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate35-image.imageset/purple_alt2.png
vendored
Normal file
After Width: | Height: | Size: 48 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate36-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "stripe_alt.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate36-image.imageset/stripe_alt.png
vendored
Normal file
After Width: | Height: | Size: 28 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate37-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/AppIconAlternate37-image.imageset/icon.png
vendored
Normal file
After Width: | Height: | Size: 113 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate38-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/AppIconAlternate38-image.imageset/icon.png
vendored
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate39-image.imageset/Alternate-48-fs8.png
vendored
Normal file
After Width: | Height: | Size: 102 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate39-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate-48-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate4-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon7.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate4-image.imageset/icon7.png
vendored
Normal file
After Width: | Height: | Size: 110 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate40-image.imageset/Alternate-49-fs8.png
vendored
Normal file
After Width: | Height: | Size: 106 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate40-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Alternate-49-fs8.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate41-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "e2a44f35b779f021.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate41-image.imageset/e2a44f35b779f021.png
vendored
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate42-image.imageset/4c26b880d454e2ec.png
vendored
Normal file
After Width: | Height: | Size: 109 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate42-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "4c26b880d454e2ec.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate43-image.imageset/63245c61df096188.png
vendored
Normal file
After Width: | Height: | Size: 128 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate43-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "63245c61df096188.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
21
IceCubesApp/Assets.xcassets/AppIconAlternate44-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon38.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
IceCubesApp/Assets.xcassets/AppIconAlternate44-image.imageset/icon38.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
21
IceCubesApp/Assets.xcassets/AppIconAlternate45-image.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "icon39.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|