Editor character count + settings instance rules

This commit is contained in:
Thomas Ricouard 2022-12-28 08:06:46 +01:00
parent 1b53180faf
commit 5b9f91abd1
5 changed files with 75 additions and 10 deletions

View File

@ -11,6 +11,7 @@ struct IceCubesApp: App {
@Environment(\.scenePhase) private var scenePhase
@StateObject private var appAccountsManager = AppAccountsManager()
@StateObject private var currenInstance = CurrentInstance()
@StateObject private var currentAccount = CurrentAccount()
@StateObject private var watcher = StreamWatcher()
@StateObject private var quickLook = QuickLook()
@ -56,6 +57,7 @@ struct IceCubesApp: App {
.environmentObject(appAccountsManager.currentClient)
.environmentObject(quickLook)
.environmentObject(currentAccount)
.environmentObject(currenInstance)
.environmentObject(theme)
.environmentObject(watcher)
.quickLookPreview($quickLook.url, in: quickLook.urls)
@ -67,6 +69,7 @@ struct IceCubesApp: App {
private func setNewClientsInEnv(client: Client) {
currentAccount.setClient(client: client)
currenInstance.setClient(client: client)
watcher.setClient(client: client)
}

View File

@ -9,12 +9,12 @@ import DesignSystem
struct SettingsTabs: View {
@Environment(\.openURL) private var openURL
@EnvironmentObject private var client: Client
@EnvironmentObject private var currentInstance: CurrentInstance
@EnvironmentObject private var appAccountsManager: AppAccountsManager
@EnvironmentObject private var theme: Theme
@State private var signInInProgress = false
@State private var accountData: Account?
@State private var instanceData: Instance?
@State private var signInServer = IceCubesApp.defaultServer
var body: some View {
@ -37,7 +37,7 @@ struct SettingsTabs: View {
if appAccountsManager.currentAccount.oauthToken != nil {
signInInProgress = true
await refreshAccountInfo()
await refreshInstanceInfo()
await currentInstance.fetchCurrentInstance()
signInInProgress = false
}
}
@ -77,7 +77,7 @@ struct SettingsTabs: View {
@ViewBuilder
private var instanceSection: some View {
if let instanceData {
if let instanceData = currentInstance.instance {
Section("Instance info") {
LabeledContent("Name", value: instanceData.title)
Text(instanceData.shortDescription)
@ -87,6 +87,12 @@ struct SettingsTabs: View {
LabeledContent("Posts", value: "\(instanceData.stats.statusCount)")
LabeledContent("Domains", value: "\(instanceData.stats.domainCount)")
}
Section("Instance rules") {
ForEach(instanceData.rules) { rule in
Text(rule.text)
}
}
}
}
@ -127,7 +133,6 @@ struct SettingsTabs: View {
private var signOutButton: some View {
Button {
instanceData = nil
accountData = nil
appAccountsManager.delete(account: appAccountsManager.currentAccount)
} label: {
@ -151,7 +156,7 @@ struct SettingsTabs: View {
let oauthToken = try await client.continueOauthFlow(url: url)
appAccountsManager.add(account: AppAccount(server: client.server, oauthToken: oauthToken))
await refreshAccountInfo()
await refreshInstanceInfo()
await currentInstance.fetchCurrentInstance()
signInInProgress = false
} catch {
signInInProgress = false
@ -161,8 +166,4 @@ struct SettingsTabs: View {
private func refreshAccountInfo() async {
accountData = try? await client.get(endpoint: Accounts.verifyCredentials)
}
private func refreshInstanceInfo() async {
instanceData = try? await client.get(endpoint: Instances.instance)
}
}

View File

@ -0,0 +1,28 @@
import Foundation
import Models
import Network
@MainActor
public class CurrentInstance: ObservableObject {
@Published public private(set) var instance: Instance?
private var client: Client?
public init() {
}
public func setClient(client: Client) {
self.client = client
Task {
await fetchCurrentInstance()
}
}
public func fetchCurrentInstance() async {
guard let client = client else { return }
Task {
instance = try? await client.get(endpoint: Instances.instance)
}
}
}

View File

@ -7,6 +7,28 @@ public struct Instance: Codable {
public let domainCount: Int
}
public struct Configuration: Codable {
public struct Statuses: Codable {
public let maxCharacters: Int
public let maxMediaAttachments: Int
}
public struct Polls: Codable {
public let maxOptions: Int
public let maxCharactersPerOption: Int
public let minExpiration: Int
public let maxExpiration: Int
}
public let statuses: Statuses
public let polls: Polls
}
public struct Rule: Codable, Identifiable {
public let id: String
public let text: String
}
public let title: String
public let shortDescription: String
public let email: String
@ -15,4 +37,6 @@ public struct Instance: Codable {
public let languages: [String]
public let registrations: Bool
public let thumbnail: URL?
public let configuration: Configuration
public let rules: [Rule]
}

View File

@ -11,6 +11,7 @@ import NukeUI
public struct StatusEditorView: View {
@EnvironmentObject private var quicklook: QuickLook
@EnvironmentObject private var client: Client
@EnvironmentObject private var currentInstance: CurrentInstance
@EnvironmentObject private var currentAccount: CurrentAccount
@Environment(\.dismiss) private var dismiss
@ -195,10 +196,12 @@ public struct StatusEditorView: View {
} label: {
Image(systemName: "number")
}
visibilityMenu
Spacer()
visibilityMenu
characterCountView
}
.padding(.horizontal, DS.Constants.layoutPadding)
.padding(.vertical, 12)
@ -206,6 +209,12 @@ public struct StatusEditorView: View {
}
}
private var characterCountView: some View {
Text("\((currentInstance.instance?.configuration.statuses.maxCharacters ?? 500) - viewModel.statusText.string.utf16.count)")
.foregroundColor(.gray)
.font(.callout)
}
private var visibilityMenu: some View {
Menu {
ForEach(Models.Visibility.allCases, id: \.self) { visibility in