mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-12-22 07:06:40 +00:00
Account tab + brand color
This commit is contained in:
parent
3d7042832e
commit
8def548913
11 changed files with 113 additions and 8 deletions
|
@ -13,6 +13,7 @@
|
|||
9F35DB44294F9A7D00B3281A /* Status in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB43294F9A7D00B3281A /* Status */; };
|
||||
9F35DB4729506F6600B3281A /* NotificationTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4629506F6600B3281A /* NotificationTab.swift */; };
|
||||
9F35DB4A29506FA100B3281A /* Notifications in Frameworks */ = {isa = PBXBuildFile; productRef = 9F35DB4929506FA100B3281A /* Notifications */; };
|
||||
9F35DB4C2952005C00B3281A /* AccountTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F35DB4B2952005C00B3281A /* AccountTab.swift */; };
|
||||
9F398AA62935FE8A00A889F2 /* AppRouteur.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F398AA52935FE8A00A889F2 /* AppRouteur.swift */; };
|
||||
9F398AA92935FFDB00A889F2 /* Account in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AA82935FFDB00A889F2 /* Account */; };
|
||||
9F398AAB2935FFDB00A889F2 /* Models in Frameworks */ = {isa = PBXBuildFile; productRef = 9F398AAA2935FFDB00A889F2 /* Models */; };
|
||||
|
@ -36,6 +37,7 @@
|
|||
9F35DB45294FA04C00B3281A /* DesignSystem */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = DesignSystem; path = Packages/DesignSystem; sourceTree = "<group>"; };
|
||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTab.swift; sourceTree = "<group>"; };
|
||||
9F35DB4829506F7F00B3281A /* Notifications */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Notifications; path = Packages/Notifications; sourceTree = "<group>"; };
|
||||
9F35DB4B2952005C00B3281A /* AccountTab.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTab.swift; sourceTree = "<group>"; };
|
||||
9F398AA32935F90100A889F2 /* Models */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Models; path = Packages/Models; sourceTree = "<group>"; };
|
||||
9F398AA52935FE8A00A889F2 /* AppRouteur.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppRouteur.swift; sourceTree = "<group>"; };
|
||||
9F398AAC2936005300A889F2 /* Account */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Account; path = Packages/Account; sourceTree = "<group>"; };
|
||||
|
@ -95,6 +97,7 @@
|
|||
9FE151A4293C90EA00E9683D /* Settings */,
|
||||
9F398AB229360A4C00A889F2 /* TimelineTab.swift */,
|
||||
9F35DB4629506F6600B3281A /* NotificationTab.swift */,
|
||||
9F35DB4B2952005C00B3281A /* AccountTab.swift */,
|
||||
);
|
||||
path = Tabs;
|
||||
sourceTree = "<group>";
|
||||
|
@ -199,7 +202,7 @@
|
|||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1410;
|
||||
LastUpgradeCheck = 1410;
|
||||
LastUpgradeCheck = 1420;
|
||||
TargetAttributes = {
|
||||
9FBFE638292A715500C250E9 = {
|
||||
CreatedOnToolsVersion = 14.1;
|
||||
|
@ -245,6 +248,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9FE151A6293C90F900E9683D /* IconSelectorView.swift in Sources */,
|
||||
9F35DB4C2952005C00B3281A /* AccountTab.swift in Sources */,
|
||||
9FAE4ACB293783B000772766 /* SettingsTab.swift in Sources */,
|
||||
9FAE4AD32937A0C600772766 /* AppAccountsManager.swift in Sources */,
|
||||
9F398AB329360A4C00A889F2 /* TimelineTab.swift in Sources */,
|
||||
|
@ -291,6 +295,7 @@
|
|||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -349,6 +354,7 @@
|
|||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -375,8 +381,10 @@
|
|||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 200;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
@ -416,8 +424,10 @@
|
|||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = IceCubesApp/IceCubesApp.entitlements;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 200;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"IceCubesApp/Resources\"";
|
||||
DEVELOPMENT_TEAM = Z6P74P6T99;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1410"
|
||||
LastUpgradeVersion = "1420"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -21,12 +21,17 @@ struct IceCubesApp: App {
|
|||
.tabItem {
|
||||
Label("Notifications", systemImage: "bell")
|
||||
}
|
||||
AccountTab()
|
||||
.tabItem {
|
||||
Label("Profile", systemImage: "person.circle")
|
||||
}
|
||||
}
|
||||
SettingsTabs()
|
||||
.tabItem {
|
||||
Label("Settings", systemImage: "gear")
|
||||
}
|
||||
}
|
||||
.tint(.brand)
|
||||
.environmentObject(appAccountsManager)
|
||||
.environmentObject(appAccountsManager.currentClient)
|
||||
}
|
||||
|
|
45
IceCubesApp/App/Tabs/AccountTab.swift
Normal file
45
IceCubesApp/App/Tabs/AccountTab.swift
Normal file
|
@ -0,0 +1,45 @@
|
|||
import SwiftUI
|
||||
import Routeur
|
||||
import Network
|
||||
import Account
|
||||
import Models
|
||||
import Shimmer
|
||||
|
||||
struct AccountTab: View {
|
||||
@EnvironmentObject private var client: Client
|
||||
@StateObject private var routeurPath = RouterPath()
|
||||
@State private var loggedUser: Account?
|
||||
|
||||
var body: some View {
|
||||
NavigationStack(path: $routeurPath.path) {
|
||||
if let loggedUser {
|
||||
AccountDetailView(account: loggedUser, isCurrentUser: true)
|
||||
.withAppRouteur()
|
||||
.withSheetDestinations(sheetDestinations: $routeurPath.presentedSheet)
|
||||
} else {
|
||||
AccountDetailView(account: .placeholder())
|
||||
.redacted(reason: .placeholder)
|
||||
.shimmering()
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
Task {
|
||||
await fetchUser(client: client)
|
||||
}
|
||||
}
|
||||
.onChange(of: client) { newClient in
|
||||
Task {
|
||||
await fetchUser(client: newClient)
|
||||
}
|
||||
}
|
||||
.environmentObject(routeurPath)
|
||||
}
|
||||
|
||||
|
||||
private func fetchUser(client: Client) async {
|
||||
guard client.isAuth else { return }
|
||||
Task {
|
||||
loggedUser = try? await client.get(endpoint: Accounts.verifyCredentials)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,12 +10,16 @@ public struct AccountDetailView: View {
|
|||
@StateObject private var viewModel: AccountDetailViewModel
|
||||
@State private var scrollOffset: CGFloat = 0
|
||||
|
||||
private let isCurrentUser: Bool
|
||||
|
||||
public init(accountId: String) {
|
||||
_viewModel = StateObject(wrappedValue: .init(accountId: accountId))
|
||||
isCurrentUser = false
|
||||
}
|
||||
|
||||
public init(account: Account) {
|
||||
public init(account: Account, isCurrentUser: Bool = false) {
|
||||
_viewModel = StateObject(wrappedValue: .init(account: account))
|
||||
self.isCurrentUser = isCurrentUser
|
||||
}
|
||||
|
||||
public var body: some View {
|
||||
|
@ -32,7 +36,15 @@ public struct AccountDetailView: View {
|
|||
.task {
|
||||
viewModel.client = client
|
||||
await viewModel.fetchAccount()
|
||||
await viewModel.fetchStatuses()
|
||||
if viewModel.statuses.isEmpty {
|
||||
await viewModel.fetchStatuses()
|
||||
}
|
||||
}
|
||||
.refreshable {
|
||||
Task {
|
||||
await viewModel.fetchAccount()
|
||||
await viewModel.fetchStatuses()
|
||||
}
|
||||
}
|
||||
.edgesIgnoringSafeArea(.top)
|
||||
.navigationTitle(Text(scrollOffset < -20 ? viewModel.title : ""))
|
||||
|
|
|
@ -18,7 +18,7 @@ class AccountDetailViewModel: ObservableObject, StatusesFetcher {
|
|||
@Published var title: String = ""
|
||||
|
||||
private var account: Account?
|
||||
private var statuses: [Status] = []
|
||||
private(set) var statuses: [Status] = []
|
||||
|
||||
init(accountId: String) {
|
||||
self.accountId = accountId
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import SwiftUI
|
||||
|
||||
extension Color {
|
||||
public static var brand: Color {
|
||||
Color("brand", bundle: .module)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "255",
|
||||
"green" : "90",
|
||||
"red" : "89"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Foundation
|
||||
|
||||
public struct App: Codable, Identifiable {
|
||||
public struct InstanceApp: Codable, Identifiable {
|
||||
public let id: String
|
||||
public let name: String
|
||||
public let website: URL?
|
|
@ -24,7 +24,7 @@ public class Client: ObservableObject, Equatable {
|
|||
private let decoder = JSONDecoder()
|
||||
|
||||
/// Only used as a transitionary app while in the oauth flow.
|
||||
private var oauthApp: Models.App?
|
||||
private var oauthApp: InstanceApp?
|
||||
|
||||
private var oauthToken: OauthToken?
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class Client: ObservableObject, Equatable {
|
|||
}
|
||||
|
||||
public func oauthURL() async throws -> URL {
|
||||
let app: Models.App = try await post(endpoint: Apps.registerApp)
|
||||
let app: InstanceApp = try await post(endpoint: Apps.registerApp)
|
||||
self.oauthApp = app
|
||||
return makeURL(endpoint: Oauth.authorize(clientId: app.clientId))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue