Add changing tint color.

This commit is contained in:
Marcin Czachursk 2023-01-12 18:34:48 +01:00
parent 8b251fb617
commit 2e95d2b862
25 changed files with 654 additions and 28 deletions

View File

@ -85,6 +85,7 @@
F8A93D802965FED4001D8331 /* AccountService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A93D7F2965FED4001D8331 /* AccountService.swift */; };
F8C14392296AF0B3001FE31D /* String+Exif.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C14391296AF0B3001FE31D /* String+Exif.swift */; };
F8C14394296AF21B001FE31D /* Double+Round.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8C14393296AF21B001FE31D /* Double+Round.swift */; };
F8CC95CE2970761D00C9C2AC /* TintColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8CC95CD2970761D00C9C2AC /* TintColor.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -164,8 +165,10 @@
F89A46DD296EABA20062125F /* StatusPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusPlaceholder.swift; sourceTree = "<group>"; };
F8A93D7D2965FD89001D8331 /* UserProfileView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileView.swift; sourceTree = "<group>"; };
F8A93D7F2965FED4001D8331 /* AccountService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountService.swift; sourceTree = "<group>"; };
F8AF2A61297073FE00D2DA3F /* Vernissage20230112-001.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Vernissage20230112-001.xcdatamodel"; sourceTree = "<group>"; };
F8C14391296AF0B3001FE31D /* String+Exif.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Exif.swift"; sourceTree = "<group>"; };
F8C14393296AF21B001FE31D /* Double+Round.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Double+Round.swift"; sourceTree = "<group>"; };
F8CC95CD2970761D00C9C2AC /* TintColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TintColor.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -230,6 +233,7 @@
children = (
F88FAD2C295F4AD7009B20C9 /* ApplicationState.swift */,
F866F6AD29606367002E8F88 /* ApplicationViewMode.swift */,
F8CC95CD2970761D00C9C2AC /* TintColor.swift */,
);
path = Models;
sourceTree = "<group>";
@ -499,6 +503,7 @@
F85D498329642FAC00751DF7 /* AttachmentData+Comperable.swift in Sources */,
F85D497B29640C8200751DF7 /* UsernameRow.swift in Sources */,
F85D497929640B9D00751DF7 /* ImagesCarousel.swift in Sources */,
F8CC95CE2970761D00C9C2AC /* TintColor.swift in Sources */,
F89992CC296D9231005994BF /* StatusViewModel.swift in Sources */,
F80048052961850500E6868A /* StatusData+CoreDataClass.swift in Sources */,
F86B7221296C49A300EE59EC /* EmptyButtonStyle.swift in Sources */,
@ -794,9 +799,10 @@
F88C2476295C37BB0006098B /* Vernissage.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
F8AF2A61297073FE00D2DA3F /* Vernissage20230112-001.xcdatamodel */,
F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */,
);
currentVersion = F88C2477295C37BB0006098B /* Vernissage.xcdatamodel */;
currentVersion = F8AF2A61297073FE00D2DA3F /* Vernissage20230112-001.xcdatamodel */;
path = Vernissage.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "247",
"green" : "131",
"red" : "52"
"blue" : "0.969",
"green" : "0.514",
"red" : "0.204"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "248",
"green" : "167",
"red" : "74"
"blue" : "0.973",
"green" : "0.655",
"red" : "0.290"
}
},
"idiom" : "universal"

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "85",
"green" : "123",
"red" : "238"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "101",
"green" : "137",
"red" : "238"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "61",
"green" : "78",
"red" : "235"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.307",
"green" : "0.386",
"red" : "0.936"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.969",
"green" : "0.514",
"red" : "0.204"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.973",
"green" : "0.655",
"red" : "0.290"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "207",
"green" : "90",
"red" : "86"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.884",
"green" : "0.390",
"red" : "0.374"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "215",
"green" : "90",
"red" : "163"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.980",
"green" : "0.423",
"red" : "0.711"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "197",
"green" : "174",
"red" : "88"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.875",
"green" : "0.767",
"red" : "0.490"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "102",
"green" : "195",
"red" : "101"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.495",
"green" : "0.844",
"red" : "0.540"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "68",
"green" : "204",
"red" : "246"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.386",
"green" : "0.827",
"red" : "0.957"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "54",
"green" : "152",
"red" : "241"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.321",
"green" : "0.651",
"red" : "0.957"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "90",
"green" : "68",
"red" : "235"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.413",
"green" : "0.352",
"red" : "0.930"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,6 +1,6 @@
//
// https://mczachurski.dev
// Copyright © 2022 Marcin Czachurski and the repository contributors.
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
@ -17,9 +17,6 @@ extension ApplicationSettings {
}
@NSManaged public var currentAccount: String?
}
extension ApplicationSettings : Identifiable {
@NSManaged public var tintColor: Int32
}

View File

@ -38,6 +38,12 @@ class ApplicationSettingsHandler {
CoreDataHandler.shared.save()
}
func setDefaultTintColor(tintColor: TintColor) {
let defaultSettings = self.getDefaultSettings()
defaultSettings.tintColor = Int32(tintColor.rawValue)
CoreDataHandler.shared.save()
}
private func createApplicationSettingsEntity() -> ApplicationSettings {
let context = CoreDataHandler.shared.container.viewContext
return ApplicationSettings(context: context)

View File

@ -13,5 +13,14 @@ extension Color {
static let lightGrayColor = Color("LightGrayColor")
static let mainTextColor = Color("MainTextColor")
static let selectedRowColor = Color("SelectedRowColor")
static let accentColor1 = Color("AccentColor1")
static let accentColor2 = Color("AccentColor2")
static let accentColor3 = Color("AccentColor3")
static let accentColor4 = Color("AccentColor4")
static let accentColor5 = Color("AccentColor5")
static let accentColor6 = Color("AccentColor6")
static let accentColor7 = Color("AccentColor7")
static let accentColor8 = Color("AccentColor8")
static let accentColor9 = Color("AccentColor9")
static let accentColor10 = Color("AccentColor10")
}

View File

@ -5,6 +5,7 @@
//
import Foundation
import SwiftUI
import MastodonKit
public class ApplicationState: ObservableObject {
@ -12,6 +13,7 @@ public class ApplicationState: ObservableObject {
private init() { }
@Published var accountData: AccountData?
@Published var tintColor = TintColor.accentColor2
@Published var showInteractionStatusId = ""
}

View File

@ -0,0 +1,37 @@
//
// https://mczachurski.dev
// Copyright © 2023 Marcin Czachurski and the repository contributors.
// Licensed under the MIT License.
//
import SwiftUI
public enum TintColor: Int {
case accentColor1, accentColor2, accentColor3, accentColor4, accentColor5,
accentColor6, accentColor7, accentColor8, accentColor9, accentColor10
public func color() -> Color {
switch self {
case .accentColor1:
return Color.accentColor1
case .accentColor2:
return Color.accentColor2
case .accentColor3:
return Color.accentColor3
case .accentColor4:
return Color.accentColor4
case .accentColor5:
return Color.accentColor5
case .accentColor6:
return Color.accentColor6
case .accentColor7:
return Color.accentColor7
case .accentColor8:
return Color.accentColor8
case .accentColor9:
return Color.accentColor9
case .accentColor10:
return Color.accentColor10
}
}
}

View File

@ -8,7 +8,7 @@ import SwiftUI
import MastodonKit
import OAuthSwift
class SceneDelegate: NSObject, UISceneDelegate {
class SceneDelegate: NSObject, UISceneDelegate {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
return

View File

@ -3,6 +3,6 @@
<plist version="1.0">
<dict>
<key>_XCCurrentVersionName</key>
<string>Vernissage.xcdatamodel</string>
<string>Vernissage20230112-001.xcdatamodel</string>
</dict>
</plist>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22C65" minimumToolsVersion="Automatic" sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
<entity name="AccountData" representedClassName="AccountData" syncable="YES">
<attribute name="accessToken" optional="YES" attributeType="String"/>
<attribute name="acct" attributeType="String"/>
<attribute name="avatar" optional="YES" attributeType="URI"/>
<attribute name="avatarData" optional="YES" attributeType="Binary"/>
<attribute name="clientId" attributeType="String"/>
<attribute name="clientSecret" attributeType="String"/>
<attribute name="clientVapidKey" attributeType="String"/>
<attribute name="createdAt" attributeType="String"/>
<attribute name="displayName" optional="YES" attributeType="String"/>
<attribute name="followersCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="followingCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="header" optional="YES" attributeType="URI"/>
<attribute name="id" attributeType="String"/>
<attribute name="locked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="note" optional="YES" attributeType="String"/>
<attribute name="serverUrl" attributeType="URI"/>
<attribute name="statusesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="url" optional="YES" attributeType="URI"/>
<attribute name="username" attributeType="String"/>
<relationship name="statuses" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="StatusData" inverseName="pixelfedAccount" inverseEntity="StatusData"/>
</entity>
<entity name="ApplicationSettings" representedClassName="ApplicationSettings" syncable="YES">
<attribute name="currentAccount" optional="YES" attributeType="String"/>
<attribute name="tintColor" attributeType="Integer 32" defaultValueString="2" usesScalarValueType="YES"/>
</entity>
<entity name="AttachmentData" representedClassName="AttachmentData" syncable="YES">
<attribute name="blurhash" optional="YES" attributeType="String"/>
<attribute name="data" attributeType="Binary" allowsExternalBinaryDataStorage="YES"/>
<attribute name="exifCamera" optional="YES" attributeType="String"/>
<attribute name="exifCreatedDate" optional="YES" attributeType="String"/>
<attribute name="exifExposure" optional="YES" attributeType="String"/>
<attribute name="exifLens" optional="YES" attributeType="String"/>
<attribute name="id" attributeType="String"/>
<attribute name="metaImageHeight" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="metaImageWidth" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="previewUrl" optional="YES" attributeType="URI"/>
<attribute name="remoteUrl" optional="YES" attributeType="URI"/>
<attribute name="statusId" attributeType="String"/>
<attribute name="text" optional="YES" attributeType="String"/>
<attribute name="type" attributeType="String"/>
<attribute name="url" attributeType="URI"/>
<relationship name="statusRelation" maxCount="1" deletionRule="Cascade" destinationEntity="StatusData" inverseName="attachmentRelation" inverseEntity="StatusData"/>
</entity>
<entity name="StatusData" representedClassName="StatusData" syncable="YES">
<attribute name="accountAvatar" optional="YES" attributeType="URI"/>
<attribute name="accountDisplayName" optional="YES" attributeType="String"/>
<attribute name="accountId" attributeType="String"/>
<attribute name="accountUsername" optional="YES" attributeType="String"/>
<attribute name="applicationName" optional="YES" attributeType="String"/>
<attribute name="applicationWebsite" optional="YES" attributeType="URI"/>
<attribute name="bookmarked" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="content" attributeType="String"/>
<attribute name="createdAt" attributeType="String"/>
<attribute name="favourited" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="favouritesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="id" attributeType="String"/>
<attribute name="inReplyToAccount" optional="YES" attributeType="String"/>
<attribute name="inReplyToId" optional="YES" attributeType="String"/>
<attribute name="muted" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="pinned" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="reblogged" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="reblogsCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="repliesCount" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="sensitive" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
<attribute name="spoilerText" optional="YES" attributeType="String"/>
<attribute name="uri" attributeType="String"/>
<attribute name="url" optional="YES" attributeType="URI"/>
<attribute name="visibility" attributeType="String"/>
<relationship name="attachmentRelation" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="AttachmentData" inverseName="statusRelation" inverseEntity="AttachmentData"/>
<relationship name="pixelfedAccount" maxCount="1" deletionRule="No Action" destinationEntity="AccountData" inverseName="statuses" inverseEntity="AccountData"/>
</entity>
</model>

View File

@ -14,6 +14,7 @@ struct VernissageApp: App {
let applicationState = ApplicationState.shared
@State var applicationViewMode: ApplicationViewMode = .loading
@State var tintColor = ApplicationState.shared.tintColor.color()
var body: some Scene {
WindowGroup {
@ -28,12 +29,21 @@ struct VernissageApp: App {
.environment(\.managedObjectContext, coreDataHandler.container.viewContext)
.environmentObject(applicationState)
case .mainView:
MainView()
.environment(\.managedObjectContext, coreDataHandler.container.viewContext)
.environmentObject(applicationState)
MainView { color in
self.tintColor = color.color()
}
.environment(\.managedObjectContext, coreDataHandler.container.viewContext)
.environmentObject(applicationState)
}
}
.task {
.tint(self.tintColor)
.task {
let defaultSettings = ApplicationSettingsHandler.shared.getDefaultSettings()
if let tintColor = TintColor(rawValue: Int(defaultSettings.tintColor)) {
self.applicationState.tintColor = tintColor
self.tintColor = tintColor.color()
}
await AuthorizationService.shared.verifyAccount({ accountData in
guard let accountData = accountData else {
self.applicationViewMode = .signIn

View File

@ -10,10 +10,19 @@ import CoreData
import MastodonKit
struct MainView: View {
enum Sheet: String, Identifiable {
case settings, compose
var id: String { rawValue }
}
@Environment(\.managedObjectContext) private var viewContext
@EnvironmentObject var applicationState: ApplicationState
var onTintChange: ((TintColor) -> Void)?
@State private var showSettings = false
@State private var sheet: Sheet?
@State private var navBarTitle: String = "Home"
@State private var viewMode: ViewMode = .home {
didSet {
@ -31,12 +40,20 @@ struct MainView: View {
self.getMainView()
.navigationBarTitle(navBarTitle)
.navigationBarTitleDisplayMode(.inline)
.sheet(isPresented: $showSettings, content: {
SettingsView()
.sheet(item: $sheet, content: { item in
switch item {
case .settings:
SettingsView { color in
self.onTintChange?(color)
}
case .compose:
ComposeView(statusViewModel: .constant(nil))
}
})
.toolbar {
self.getLeadingToolbar()
self.getPrincipalToolbar()
self.getTrailingToolbar()
}
}
@ -148,7 +165,7 @@ struct MainView: View {
Divider()
Button {
self.showSettings.toggle()
self.sheet = .settings
} label: {
Label("Settings", systemImage: "gear")
}
@ -168,6 +185,19 @@ struct MainView: View {
}
}
@ToolbarContentBuilder
private func getTrailingToolbar() -> some ToolbarContent {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
self.sheet = .compose
} label: {
Image(systemName: "photo.stack")
.tint(.mainTextColor)
}
}
}
private func getViewTitle(viewMode: ViewMode) -> String {
switch viewMode {
case .home:

View File

@ -11,6 +11,12 @@ struct SettingsView: View {
@Environment(\.dismiss) private var dismiss
@State var accounts: [AccountData] = []
@State private var matchSystemTheme = true
var onTintChange: ((TintColor) -> Void)?
let accentColors1: [TintColor] = [.accentColor1, .accentColor2, .accentColor3, .accentColor4, .accentColor5]
let accentColors2: [TintColor] = [.accentColor6, .accentColor7, .accentColor8, .accentColor9, .accentColor10]
var body: some View {
NavigationView {
@ -32,13 +38,75 @@ struct SettingsView: View {
}
}
Section("General") {
Text("Accent")
Section("Theme") {
Toggle("Match system", isOn: $matchSystemTheme)
.toggleStyle(SwitchToggleStyle(tint: .accentColor))
Text("Light")
Text("Dark")
}
Section("About") {
Text("Website")
Text("License")
Section("Accent") {
VStack(alignment: .leading) {
HStack(alignment: .center) {
ForEach(accentColors1, id: \.self) { color in
ZStack {
Circle()
.fill(color.color())
.frame(width: 36, height: 36)
.onTapGesture {
self.applicationState.tintColor = color
ApplicationSettingsHandler.shared.setDefaultTintColor(tintColor: color)
self.onTintChange?(color)
}
if color == self.applicationState.tintColor {
Image(systemName: "checkmark")
.tint(Color.mainTextColor)
.fontWeight(.bold)
}
}
if color != accentColors1.last {
Spacer()
}
}
}
.padding(.vertical, 8)
HStack(alignment: .center) {
ForEach(accentColors2, id: \.self) { color in
ZStack {
Circle()
.fill(color.color())
.frame(width: 36, height: 36)
.onTapGesture {
self.applicationState.tintColor = color
ApplicationSettingsHandler.shared.setDefaultTintColor(tintColor: color)
self.onTintChange?(color)
}
if color == self.applicationState.tintColor {
Image(systemName: "checkmark")
.tint(Color.mainTextColor)
.fontWeight(.bold)
}
}
if color != accentColors2.last {
Spacer()
}
}
}
.padding(.vertical, 8)
}
}
Section("Other") {
Text("Third party") // Link to dependeinces
Text("Report a bug")
Text("Follow me on Mastodon")
}
Section() {
Text("Version") // Link to dependeinces
}
}
.frame(alignment: .topLeading)

View File

@ -110,7 +110,7 @@ struct InteractionRow: View {
}
}
.font(.title3)
.fontWeight(.semibold)
.fontWeight(.bold)
.onAppear {
self.refreshCounters()
}