diff --git a/V2er/Assets.xcassets/Colors/AppBackground.colorset/Contents.json b/V2er/Assets.xcassets/Colors/AppBackground.colorset/Contents.json
new file mode 100644
index 0000000..3d8ee2e
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/AppBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.980",
+ "green" : "0.980",
+ "red" : "0.980"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.110",
+ "green" : "0.110",
+ "red" : "0.110"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/BackgroundColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/BackgroundColor.colorset/Contents.json
new file mode 100644
index 0000000..3d84274
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/BackgroundColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0.886",
+ "green" : "0.886",
+ "red" : "0.886"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0.118",
+ "green" : "0.110",
+ "red" : "0.110"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/BorderColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/BorderColor.colorset/Contents.json
new file mode 100644
index 0000000..462bf3e
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/BorderColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0.910",
+ "green" : "0.910",
+ "red" : "0.910"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.800",
+ "blue" : "0.247",
+ "green" : "0.235",
+ "red" : "0.235"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/DimColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/DimColor.colorset/Contents.json
new file mode 100644
index 0000000..f6c9cf5
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/DimColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.600",
+ "blue" : "0.000",
+ "green" : "0.000",
+ "red" : "0.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.600",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/ItemBackground.colorset/Contents.json b/V2er/Assets.xcassets/Colors/ItemBackground.colorset/Contents.json
new file mode 100644
index 0000000..a431dd9
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/ItemBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x1E",
+ "green" : "0x1C",
+ "red" : "0x1C"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/LightGray.colorset/Contents.json b/V2er/Assets.xcassets/Colors/LightGray.colorset/Contents.json
new file mode 100644
index 0000000..1beb2f7
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/LightGray.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF5",
+ "green" : "0xF5",
+ "red" : "0xF5"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x2E",
+ "green" : "0x2C",
+ "red" : "0x2C"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/PrimaryText.colorset/Contents.json b/V2er/Assets.xcassets/Colors/PrimaryText.colorset/Contents.json
new file mode 100644
index 0000000..c4fd6eb
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/PrimaryText.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x00",
+ "green" : "0x00",
+ "red" : "0x00"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/SecondaryBackground.colorset/Contents.json b/V2er/Assets.xcassets/Colors/SecondaryBackground.colorset/Contents.json
new file mode 100644
index 0000000..cca56c7
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/SecondaryBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.961",
+ "green" : "0.961",
+ "red" : "0.961"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0.153",
+ "green" : "0.153",
+ "red" : "0.153"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/SecondaryText.colorset/Contents.json b/V2er/Assets.xcassets/Colors/SecondaryText.colorset/Contents.json
new file mode 100644
index 0000000..41b70f4
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/SecondaryText.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x55",
+ "green" : "0x55",
+ "red" : "0x55"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xAA",
+ "green" : "0xAA",
+ "red" : "0xAA"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/SelectionColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/SelectionColor.colorset/Contents.json
new file mode 100644
index 0000000..da7da1f
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/SelectionColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.900",
+ "blue" : "0.000",
+ "green" : "0.000",
+ "red" : "0.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.900",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/Separator.colorset/Contents.json b/V2er/Assets.xcassets/Colors/Separator.colorset/Contents.json
new file mode 100644
index 0000000..dbb0d23
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/Separator.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xE8",
+ "green" : "0xE8",
+ "red" : "0xE8"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x2E",
+ "green" : "0x2C",
+ "red" : "0x2C"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/TertiaryBackground.colorset/Contents.json b/V2er/Assets.xcassets/Colors/TertiaryBackground.colorset/Contents.json
new file mode 100644
index 0000000..65deedd
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/TertiaryBackground.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xF5",
+ "green" : "0xF5",
+ "red" : "0xF5"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x1A",
+ "green" : "0x1A",
+ "red" : "0x1A"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/TertiaryText.colorset/Contents.json b/V2er/Assets.xcassets/Colors/TertiaryText.colorset/Contents.json
new file mode 100644
index 0000000..3b03d34
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/TertiaryText.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x99",
+ "green" : "0x99",
+ "red" : "0x99"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x66",
+ "green" : "0x66",
+ "red" : "0x66"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/TintColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/TintColor.colorset/Contents.json
new file mode 100644
index 0000000..db7950d
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/TintColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x38",
+ "green" : "0x38",
+ "red" : "0x38"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xFF",
+ "green" : "0xFF",
+ "red" : "0xFF"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/URLColor.colorset/Contents.json b/V2er/Assets.xcassets/Colors/URLColor.colorset/Contents.json
new file mode 100644
index 0000000..84b6cc8
--- /dev/null
+++ b/V2er/Assets.xcassets/Colors/URLColor.colorset/Contents.json
@@ -0,0 +1,38 @@
+{
+ "colors" : [
+ {
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0x87",
+ "green" : "0x80",
+ "red" : "0x77"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "1.000",
+ "blue" : "0xB8",
+ "green" : "0xA3",
+ "red" : "0x94"
+ }
+ },
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/V2er/Assets.xcassets/Colors/bodyText.colorset/Contents.json b/V2er/Assets.xcassets/Colors/bodyText.colorset/Contents.json
index 6e8d0a5..94e7045 100644
--- a/V2er/Assets.xcassets/Colors/bodyText.colorset/Contents.json
+++ b/V2er/Assets.xcassets/Colors/bodyText.colorset/Contents.json
@@ -4,10 +4,28 @@
"color" : {
"color-space" : "srgb",
"components" : {
- "alpha" : "1.000",
- "blue" : "0x55",
- "green" : "0x55",
- "red" : "0x55"
+ "alpha" : "0.750",
+ "blue" : "0.000",
+ "green" : "0.000",
+ "red" : "0.000"
+ }
+ },
+ "idiom" : "universal"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "color" : {
+ "color-space" : "srgb",
+ "components" : {
+ "alpha" : "0.850",
+ "blue" : "1.000",
+ "green" : "1.000",
+ "red" : "1.000"
}
},
"idiom" : "universal"
@@ -17,4 +35,4 @@
"author" : "xcode",
"version" : 1
}
-}
+}
\ No newline at end of file
diff --git a/V2er/General/Color.swift b/V2er/General/Color.swift
index e98129a..9016edf 100644
--- a/V2er/General/Color.swift
+++ b/V2er/General/Color.swift
@@ -26,24 +26,62 @@ extension Color {
self.frame(width: .infinity)
}
- public static let border = hex(0xE8E8E8, alpha: 0.8)
- static let lightGray = hex(0xF5F5F5)
- static let almostClear = hex(0xFFFFFF, alpha: 0.000001)
- static let debugColor = hex(0xFF0000, alpha: 0.1)
-// static let bodyText = hex(0x555555)
- static let bodyText = hex(0x000000, alpha: 0.75)
- static let tintColor = hex(0x383838)
- static let bgColor = hex(0xE2E2E2, alpha: 0.8)
- static let itemBg: Color = .white
- static let dim = hex(0x000000, alpha: 0.6)
-// static let url = hex(0x60c2d4)
- static let url = hex(0x778087)
+ // MARK: - Adaptive Colors for Dark Mode
+
+ // Background Colors
+ public static let background = Color("AppBackground")
+ public static let secondaryBackground = Color("SecondaryBackground")
+ public static let tertiaryBackground = Color("TertiaryBackground")
+ public static let itemBackground = Color("ItemBackground")
+
+ // Text Colors
+ public static let primaryText = Color("PrimaryText")
+ public static let secondaryText = Color("SecondaryText")
+ public static let tertiaryText = Color("TertiaryText")
+
+ // UI Element Colors
+ public static let separator = Color("Separator")
+ public static let tint = Color("TintColor")
+ public static let selection = Color("SelectionColor")
+
+ // Legacy colors with dark mode support
+ public static let border = Color("BorderColor")
+ public static let lightGray = Color("LightGray")
+ public static let almostClear = hex(0xFFFFFF, alpha: 0.000001)
+ public static let debugColor = hex(0xFF0000, alpha: 0.1)
+ public static let bodyText = Color("BodyText")
+ public static let tintColor = Color("TintColor")
+ public static let bgColor = Color("BackgroundColor")
+ public static let itemBg = Color("ItemBackground")
+ public static let dim = Color("DimColor")
+ public static let url = Color("URLColor")
public var uiColor: UIColor {
return UIColor(self)
}
}
+// MARK: - Dynamic Color Creation
+extension Color {
+ static func dynamic(light: Color, dark: Color) -> Color {
+ return Color(UIColor { traitCollection in
+ switch traitCollection.userInterfaceStyle {
+ case .dark:
+ return UIColor(dark)
+ default:
+ return UIColor(light)
+ }
+ })
+ }
+
+ static func dynamicHex(light: Int, dark: Int, alpha: CGFloat = 1.0) -> Color {
+ return dynamic(
+ light: Color.hex(light, alpha: alpha),
+ dark: Color.hex(dark, alpha: alpha)
+ )
+ }
+}
+
extension UIColor {
convenience init(hex: Int, alpha: CGFloat = 1.0) {
let components = (
@@ -55,18 +93,47 @@ extension UIColor {
}
}
-
-
+// MARK: - Preview
struct Color_Previews: PreviewProvider {
static var previews: some View {
- VStack {
- Color.hex(0xFBFBFB).frame(width: 100, height: 100)
- Color.hex(0x00FF00, alpha: 0.2).frame(width: 100, height: 100)
- Color.hex(0xFF00FF).frame(width: 100, height: 100)
- Color.tintColor.frame(width: 100, height: 100)
- Color.lightGray.frame(width: 100, height: 100)
- Color.border.frame(width: 100, height: 100).opacity(0.5)
+ Group {
+ // Light Mode Preview
+ VStack(spacing: 20) {
+ Text("Light Mode")
+ .font(.title)
+ HStack {
+ Color.background.frame(width: 80, height: 80)
+ Color.secondaryBackground.frame(width: 80, height: 80)
+ Color.itemBackground.frame(width: 80, height: 80)
+ }
+ HStack {
+ Color.primaryText.frame(width: 80, height: 80)
+ Color.secondaryText.frame(width: 80, height: 80)
+ Color.tintColor.frame(width: 80, height: 80)
+ }
+ }
+ .padding()
+ .background(Color.background)
+ .environment(\.colorScheme, .light)
+
+ // Dark Mode Preview
+ VStack(spacing: 20) {
+ Text("Dark Mode")
+ .font(.title)
+ HStack {
+ Color.background.frame(width: 80, height: 80)
+ Color.secondaryBackground.frame(width: 80, height: 80)
+ Color.itemBackground.frame(width: 80, height: 80)
+ }
+ HStack {
+ Color.primaryText.frame(width: 80, height: 80)
+ Color.secondaryText.frame(width: 80, height: 80)
+ Color.tintColor.frame(width: 80, height: 80)
+ }
+ }
+ .padding()
+ .background(Color.background)
+ .environment(\.colorScheme, .dark)
}
-
}
-}
+}
\ No newline at end of file
diff --git a/V2er/General/V2erApp.swift b/V2er/General/V2erApp.swift
index 737d201..f35d97b 100644
--- a/V2er/General/V2erApp.swift
+++ b/V2er/General/V2erApp.swift
@@ -14,20 +14,56 @@ struct V2erApp: App {
public static var rootViewController: UIViewController?
public static var statusBarState: UIStatusBarStyle = .darkContent
public static var window: UIWindow?
+ @StateObject private var store = Store.shared
init() {
setupApperance()
}
private func setupApperance() {
+ // Navigation bar appearance will be set dynamically based on color scheme
+ let navAppearance = UINavigationBar.appearance()
+ navAppearance.isTranslucent = true
+ }
+
+ var body: some Scene {
+ WindowGroup {
+ RootView {
+ RootHostView()
+ .environmentObject(store)
+ .preferredColorScheme(store.appState.settingState.appearance.colorScheme)
+ .onAppear {
+ updateNavigationBarAppearance(for: store.appState.settingState.appearance)
+ updateWindowInterfaceStyle(for: store.appState.settingState.appearance)
+ }
+ .onChange(of: store.appState.settingState.appearance) { newValue in
+ updateNavigationBarAppearance(for: newValue)
+ updateWindowInterfaceStyle(for: newValue)
+ }
+ }
+ }
+ }
+
+ private func updateNavigationBarAppearance(for appearance: AppearanceMode) {
let navbarAppearance = UINavigationBarAppearance()
- let tintColor = UIColor.black
+
+ // Determine if we should use dark mode
+ let isDarkMode: Bool
+ switch appearance {
+ case .light:
+ isDarkMode = false
+ case .dark:
+ isDarkMode = true
+ case .system:
+ isDarkMode = UITraitCollection.current.userInterfaceStyle == .dark
+ }
+
+ let tintColor = isDarkMode ? UIColor.white : UIColor.black
navbarAppearance.titleTextAttributes = [.foregroundColor: tintColor]
navbarAppearance.largeTitleTextAttributes = [.foregroundColor: tintColor]
navbarAppearance.backgroundColor = .clear
let navAppearance = UINavigationBar.appearance()
- navAppearance.isTranslucent = true
navAppearance.standardAppearance = navbarAppearance
navAppearance.compactAppearance = navbarAppearance
navAppearance.scrollEdgeAppearance = navbarAppearance
@@ -35,12 +71,23 @@ struct V2erApp: App {
navAppearance.tintColor = tintColor
}
- var body: some Scene {
- WindowGroup {
- RootView {
- RootHostView()
- .environmentObject(Store.shared)
- }
+ private func updateWindowInterfaceStyle(for appearance: AppearanceMode) {
+ // Get all windows and update their interface style
+ guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }
+
+ let style: UIUserInterfaceStyle
+ switch appearance {
+ case .light:
+ style = .light
+ case .dark:
+ style = .dark
+ case .system:
+ style = .unspecified
+ }
+
+ // Update all windows in the scene
+ windowScene.windows.forEach { window in
+ window.overrideUserInterfaceStyle = style
}
}
diff --git a/V2er/Info.plist b/V2er/Info.plist
index bf7762a..df25606 100644
--- a/V2er/Info.plist
+++ b/V2er/Info.plist
@@ -54,8 +54,6 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
- UIUserInterfaceStyle
- Light
UIViewControllerBasedStatusBarAppearance
diff --git a/V2er/State/DataFlow/Reducers/SettingReducer.swift b/V2er/State/DataFlow/Reducers/SettingReducer.swift
index 631fec2..ec3613e 100644
--- a/V2er/State/DataFlow/Reducers/SettingReducer.swift
+++ b/V2er/State/DataFlow/Reducers/SettingReducer.swift
@@ -9,7 +9,20 @@
import Foundation
func settingStateReducer(_ state: SettingState, _ action: Action) -> (SettingState, Action?) {
- return (SettingState(), nil)
+ var state = state
+ var followingAction: Action? = action
+
+ switch action {
+ case let action as SettingActions.ChangeAppearanceAction:
+ state.appearance = action.appearance
+ // Save to UserDefaults
+ UserDefaults.standard.set(action.appearance.rawValue, forKey: "appearanceMode")
+ followingAction = nil
+ default:
+ break
+ }
+
+ return (state, followingAction)
}
diff --git a/V2er/State/DataFlow/State/SettingState.swift b/V2er/State/DataFlow/State/SettingState.swift
index 8070bc2..29b6e58 100644
--- a/V2er/State/DataFlow/State/SettingState.swift
+++ b/V2er/State/DataFlow/State/SettingState.swift
@@ -7,7 +7,54 @@
//
import Foundation
+import SwiftUI
struct SettingState: FluxState {
+ var appearance: AppearanceMode = .system
+ init() {
+ // Load saved preference
+ if let savedMode = UserDefaults.standard.string(forKey: "appearanceMode"),
+ let mode = AppearanceMode(rawValue: savedMode) {
+ self.appearance = mode
+ }
+ }
}
+
+enum AppearanceMode: String, CaseIterable {
+ case light = "light"
+ case dark = "dark"
+ case system = "system"
+
+ var displayName: String {
+ switch self {
+ case .light:
+ return "浅色"
+ case .dark:
+ return "深色"
+ case .system:
+ return "跟随系统"
+ }
+ }
+
+ var colorScheme: ColorScheme? {
+ switch self {
+ case .light:
+ return .light
+ case .dark:
+ return .dark
+ case .system:
+ return nil
+ }
+ }
+}
+
+// Temporary: Define actions here until SettingActions.swift is properly added to project
+struct SettingActions {
+ private static let R: Reducer = .setting
+
+ struct ChangeAppearanceAction: Action {
+ var target: Reducer = R
+ let appearance: AppearanceMode
+ }
+}
\ No newline at end of file
diff --git a/V2er/View/Explore/SearchPage.swift b/V2er/View/Explore/SearchPage.swift
index 5abc39a..5be5579 100644
--- a/V2er/View/Explore/SearchPage.swift
+++ b/V2er/View/Explore/SearchPage.swift
@@ -47,7 +47,7 @@ struct SearchPage: StateView {
HStack(spacing: 0) {
HStack {
Image(systemName: "magnifyingglass")
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
TextField("sov2ex", text: bindingState.keyword)
.disableAutocorrection(true)
.autocapitalization(.none)
@@ -83,7 +83,7 @@ struct SearchPage: StateView {
Divider()
}
.visualBlur()
- .background(Color.gray.opacity(0.35))
+ .background(Color.secondaryText.opacity(0.35))
}
@ViewBuilder
diff --git a/V2er/View/Feed/FeedItemView.swift b/V2er/View/Feed/FeedItemView.swift
index 8fc602b..30e6e47 100644
--- a/V2er/View/Feed/FeedItemView.swift
+++ b/V2er/View/Feed/FeedItemView.swift
@@ -30,13 +30,14 @@ struct FeedItemView: View {
}
Text(data.title.safe)
// .fontWeight(.medium)
- .foregroundColor(.bodyText)
+ .foregroundColor(.primaryText)
.greedyWidth(.leading)
.lineLimit(2)
.padding(.top, 6)
.padding(.vertical, 4)
Text("评论\(data.replyNum.safe)")
.font(.footnote)
+ .foregroundColor(.secondaryText)
.greedyWidth(.trailing)
}
.padding(12)
diff --git a/V2er/View/Feed/FeedPage.swift b/V2er/View/Feed/FeedPage.swift
index dd782c5..bbc5ca0 100644
--- a/V2er/View/Feed/FeedPage.swift
+++ b/V2er/View/Feed/FeedPage.swift
@@ -33,17 +33,23 @@ struct FeedPage: BaseHomePageView {
@ViewBuilder
private var contentView: some View {
- LazyVStack(spacing: 0) {
- ForEach(state.feedInfo.items) { item in
- NavigationLink(destination: FeedDetailPage(initData: item)) {
- FeedItemView(data: item)
+ VStack(spacing: 0) {
+ LazyVStack(spacing: 0) {
+ ForEach(state.feedInfo.items) { item in
+ NavigationLink(destination: FeedDetailPage(initData: item)) {
+ FeedItemView(data: item)
+ }
}
}
}
.updatable(autoRefresh: state.showProgressView, hasMoreData: state.hasMoreData, scrollTop(tab: .feed)) {
- await run(action: FeedActions.FetchData.Start())
+ if AccountState.hasSignIn() {
+ await run(action: FeedActions.FetchData.Start())
+ }
} loadMore: {
- await run(action: FeedActions.LoadMore.Start(state.willLoadPage))
+ if AccountState.hasSignIn() {
+ await run(action: FeedActions.LoadMore.Start(state.willLoadPage))
+ }
}
.background(Color.bgColor)
}
diff --git a/V2er/View/FeedDetail/AuthorInfoView.swift b/V2er/View/FeedDetail/AuthorInfoView.swift
index d8f875f..2085e0d 100644
--- a/V2er/View/FeedDetail/AuthorInfoView.swift
+++ b/V2er/View/FeedDetail/AuthorInfoView.swift
@@ -60,7 +60,7 @@ struct AuthorInfoView: View {
NavigationLink(destination: TagDetailPage(tag: tag, tagId: tagId)) {
Text(tag)
.font(.footnote)
- .foregroundColor(.black)
+ .foregroundColor(.primaryText)
.lineLimit(1)
.padding(.horizontal, 14)
.padding(.vertical, 8)
diff --git a/V2er/View/FeedDetail/FeedDetailPage.swift b/V2er/View/FeedDetail/FeedDetailPage.swift
index 667a906..a378bb1 100644
--- a/V2er/View/FeedDetail/FeedDetailPage.swift
+++ b/V2er/View/FeedDetail/FeedDetailPage.swift
@@ -150,7 +150,7 @@ struct FeedDetailPage: StateView, KeyboardReadable, InstanceIdentifiable {
.padding(.bottom, isKeyboardVisiable ? 0 : topSafeAreaInset().bottom * 0.9)
.padding(.top, 10)
.padding(.horizontal, 10)
- .background(Color.white)
+ .background(Color.itemBg)
}
}
diff --git a/V2er/View/FeedDetail/HtmlView.swift b/V2er/View/FeedDetail/HtmlView.swift
index c0c1e02..c1805a7 100644
--- a/V2er/View/FeedDetail/HtmlView.swift
+++ b/V2er/View/FeedDetail/HtmlView.swift
@@ -27,7 +27,8 @@ struct HtmlView: View {
var body: some View {
GeometryReader { geo in
- Webview(html: html, imgs: imgs,height: $height, rendered: $rendered)
+ Webview(html: html, imgs: imgs, height: $height, rendered: $rendered)
+ .environmentObject(Store.shared)
}
.frame(height: height)
}
@@ -39,6 +40,8 @@ fileprivate struct Webview: UIViewRepresentable, WebViewHandlerDelegate {
@Binding var height: CGFloat
@Binding var rendered: Bool
@State var loaded: Bool = false
+ @EnvironmentObject var store: Store
+ @Environment(\.colorScheme) var colorScheme
// Make a coordinator to co-ordinate with WKWebView's default delegate functions
func makeCoordinator() -> Coordinator {
@@ -70,8 +73,17 @@ fileprivate struct Webview: UIViewRepresentable, WebViewHandlerDelegate {
print("------updateUIView--------: \(self.rendered)")
// if rendered { return }
var content = Bundle.readString(name: "v2er", type: "html")
- // TODO: dark mode
- let isDark = false
+ // Determine dark mode based on app appearance setting
+ let isDark: Bool
+ let appearance = store.appState.settingState.appearance
+ switch appearance {
+ case .dark:
+ isDark = true
+ case .light:
+ isDark = false
+ case .system:
+ isDark = colorScheme == .dark
+ }
let fontSize = 16
let params = "\(isDark), \(fontSize)"
content = content?.replace(segs: "{injecttedContent}", with: html ?? .empty)
diff --git a/V2er/View/FeedDetail/ReplyItemView.swift b/V2er/View/FeedDetail/ReplyItemView.swift
index ba54266..1736dc1 100644
--- a/V2er/View/FeedDetail/ReplyItemView.swift
+++ b/V2er/View/FeedDetail/ReplyItemView.swift
@@ -22,7 +22,7 @@ struct ReplyItemView: View {
.font(.system(size: 8))
.padding(.horizontal, 4)
.padding(.vertical, 2)
- .cornerBorder(radius: 3, borderWidth: 0.8, color: .black)
+ .cornerBorder(radius: 3, borderWidth: 0.8, color: .primaryText)
.padding(.top, 2)
.hide(!info.isOwner)
}
diff --git a/V2er/View/Login/LoginPage.swift b/V2er/View/Login/LoginPage.swift
index fe08e1a..5fc0108 100644
--- a/V2er/View/Login/LoginPage.swift
+++ b/V2er/View/Login/LoginPage.swift
@@ -91,8 +91,8 @@ struct LoginPage: StateView {
.submitLabel(.continue)
.padding(.horizontal, padding)
.frame(maxWidth: .infinity, maxHeight: height)
- Color.gray
- .opacity(0.2)
+ Color.separator
+ .opacity(0.5)
.padding(.vertical, 14)
.frame(width: 1.5, height: height)
.padding(.horizontal, 2)
@@ -116,8 +116,8 @@ struct LoginPage: StateView {
.submitLabel(.go)
.keyboardType(.asciiCapable)
.disableAutocorrection(true)
- Color.gray
- .opacity(0.2)
+ Color.separator
+ .opacity(0.5)
.padding(.vertical, 14)
.frame(width: 1.5, height: height)
.padding(.horizontal, 2)
@@ -152,7 +152,7 @@ struct LoginPage: StateView {
} label: {
Text("Login")
.font(.headline)
- .foregroundColor(.white)
+ .foregroundColor(Color.itemBackground)
.padding()
.greedyWidth()
.background(Color.tintColor)
diff --git a/V2er/View/Login/TwoStepLoginPage.swift b/V2er/View/Login/TwoStepLoginPage.swift
index d951ebd..d33fac6 100644
--- a/V2er/View/Login/TwoStepLoginPage.swift
+++ b/V2er/View/Login/TwoStepLoginPage.swift
@@ -19,26 +19,34 @@ struct TwoStepLoginPage: View {
VStack(spacing: 16) {
Text("两步验证")
.font(.subheadline)
+ .foregroundColor(.primaryText)
TextField("2FA码", text: $twoStepCode)
+ .textFieldStyle(RoundedBorderTextFieldStyle())
+ .keyboardType(.numberPad)
+ .foregroundColor(.primaryText)
.padding(.vertical, 6)
.padding(.horizontal)
- .background(Color.white.opacity(0.8))
- .cornerBorder(radius: 8)
HStack(spacing: 16) {
Spacer()
Button {
dispatch(LoginActions.TwoStepLoginCancel())
- } label: { Text("取消").opacity(0.8) }
+ } label: {
+ Text("取消")
+ .foregroundColor(.secondaryText)
+ }
Button {
dispatch(LoginActions.TwoStepLogin(input: twoStepCode))
- } label: { Text("确定") }
+ } label: {
+ Text("确定")
+ .foregroundColor(.tintColor)
+ .fontWeight(.medium)
+ }
.disabled(twoStepCode.isEmpty)
}
- .foregroundColor(.bodyText)
}
.padding(20)
- .visualBlur()
- .cornerBorder(radius: 20, borderWidth: 0)
+ .background(Color.secondaryBackground)
+ .cornerRadius(20)
.padding(50)
}
diff --git a/V2er/View/Me/CreateTopicPage.swift b/V2er/View/Me/CreateTopicPage.swift
index e84a51c..a83cf3f 100644
--- a/V2er/View/Me/CreateTopicPage.swift
+++ b/V2er/View/Me/CreateTopicPage.swift
@@ -66,7 +66,7 @@ struct CreateTopicPage: StateView {
} label: {
Text(isPreviewing ? "编辑" : "预览")
.font(.callout)
- .foregroundColor(Color.white)
+ .foregroundColor(Color.background)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(Color.tintColor)
@@ -106,7 +106,7 @@ struct CreateTopicPage: StateView {
// show placeholder
Text("如果标题能够表达完整内容, 此处可为空")
.greedyFrame(.topLeading)
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
.debug()
} else if isPreviewing {
Text(state.content.attributedString)
@@ -135,7 +135,7 @@ struct CreateTopicPage: StateView {
} label: {
Text("发布主题")
.font(.callout)
- .foregroundColor(Color.white)
+ .foregroundColor(Color.background)
.padding(.horizontal, 12)
.padding(.vertical, 8)
.background(Color.tintColor)
@@ -156,12 +156,12 @@ struct CreateTopicPage: StateView {
private var sectionItemView: some View {
HStack {
Image(systemName: "grid.circle")
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
Text(state.selectedNode?.text ?? "选择节点")
Spacer()
Image(systemName: "chevron.right")
.font(.body.weight(.regular))
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
.padding(.trailing)
}
.padding()
diff --git a/V2er/View/Me/MePage.swift b/V2er/View/Me/MePage.swift
index 0732387..336f01a 100644
--- a/V2er/View/Me/MePage.swift
+++ b/V2er/View/Me/MePage.swift
@@ -31,17 +31,17 @@ struct MePage: BaseHomePageView {
if !AccountState.hasSignIn() {
VStack {
Text("登录查看更多")
- .foregroundColor(.white)
+ .foregroundColor(.primaryText)
.font(.title2)
Button {
dispatch(LoginActions.ShowLoginPageAction())
} label: {
Text("登录")
.font(.headline)
- .foregroundColor(.white)
+ .foregroundColor(Color.itemBackground)
.padding()
.padding(.horizontal, 50)
- .background(Color.black)
+ .background(Color.tintColor)
.cornerRadius(15)
}
}
@@ -71,12 +71,12 @@ struct MePage: BaseHomePageView {
.foregroundColor(Color.bodyText)
Image(systemName: "chevron.right")
.font(.body.weight(.regular))
- .foregroundColor(Color.gray)
+ .foregroundColor(Color.secondaryText)
}
}
.padding(.horizontal, 12)
.padding(.vertical, 16)
- .background(.white)
+ .background(Color.itemBackground)
.padding(.bottom, 8)
.to {
UserDetailPage(userId: AccountState.userName)
diff --git a/V2er/View/Me/NodeChooserPage.swift b/V2er/View/Me/NodeChooserPage.swift
index e9014f8..3b4308b 100644
--- a/V2er/View/Me/NodeChooserPage.swift
+++ b/V2er/View/Me/NodeChooserPage.swift
@@ -63,7 +63,7 @@ struct NodeChooserPage: View {
HStack {
HStack {
Image(systemName: "magnifyingglass")
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
TextField("Search ...", text: $filterText)
.disableAutocorrection(true)
.autocapitalization(.none)
diff --git a/V2er/View/Me/UserDetailPage.swift b/V2er/View/Me/UserDetailPage.swift
index 1a9b225..536df15 100644
--- a/V2er/View/Me/UserDetailPage.swift
+++ b/V2er/View/Me/UserDetailPage.swift
@@ -42,7 +42,7 @@ struct UserDetailPage: StateView {
}
var foreGroundColor: SwiftUI.Color {
- return shouldHideNavbar ? .white.opacity(0.9) : .tintColor
+ return shouldHideNavbar ? Color.primaryText.opacity(0.9) : .tintColor
}
var body: some View {
@@ -77,7 +77,7 @@ struct UserDetailPage: StateView {
.fade(duration: 0.25)
.resizable()
.blur(radius: 80, opaque: true)
- .overlay(Color.black.opacity(withAnimation {shouldHideNavbar ? 0.3 : 0.1}))
+ .overlay(Color.dynamic(light: .black, dark: .white).opacity(withAnimation {shouldHideNavbar ? 0.3 : 0.1}))
.frame(maxWidth: .infinity, maxHeight: height)
Spacer().background(.clear)
}
@@ -172,7 +172,7 @@ struct UserDetailPage: StateView {
AvatarView(url: model.avatar, size: heightOfNodeImage)
HStack(alignment: .center,spacing: 4) {
Circle()
- .fill(state.model.isOnline ? .green : .gray)
+ .fill(state.model.isOnline ? .green : Color.secondaryText)
.frame(width: 8, height: 8)
Text(model.userName)
.font(.headline.weight(.semibold))
@@ -203,7 +203,7 @@ struct UserDetailPage: StateView {
.background(Color.lightGray, in: RoundedRectangle(cornerRadius: 10))
.padding(.horizontal, 12)
.padding(.vertical, 10)
- .background(.white)
+ .background(Color.itemBackground)
.clipCorner(12, corners: [.topLeft, .topRight])
}
@@ -298,7 +298,7 @@ struct UserDetailPage: StateView {
NavigationLink(destination: TagDetailPage()) {
Text(data.tag)
.font(.footnote)
- .foregroundColor(.black)
+ .foregroundColor(Color.primaryText)
.lineLimit(1)
.padding(.horizontal, 14)
.padding(.vertical, 8)
@@ -339,14 +339,14 @@ struct UserDetailPage: StateView {
} label: {
Text(title)
.fontWeight(.bold)
- .foregroundColor(isSelected ? .white.opacity(0.9) : .tintColor)
+ .foregroundColor(isSelected ? Color.itemBackground.opacity(0.9) : .tintColor)
.frame(maxWidth: .infinity)
.padding(.vertical, 8)
.background {
VStack {
if isSelected {
RoundedRectangle(cornerRadius: 10)
- .fill(.black)
+ .fill(Color.primaryText)
.matchedGeometryEffect(id: "TAB", in: animation)
}
}
diff --git a/V2er/View/Settings/AppearanceSettingView.swift b/V2er/View/Settings/AppearanceSettingView.swift
index 095b0aa..a531739 100644
--- a/V2er/View/Settings/AppearanceSettingView.swift
+++ b/V2er/View/Settings/AppearanceSettingView.swift
@@ -9,22 +9,91 @@
import SwiftUI
struct AppearanceSettingView: View {
+ @EnvironmentObject private var store: Store
+ @State private var selectedAppearance: AppearanceMode = .system
+
var body: some View {
formView
.navBar("外观设置")
+ .onAppear {
+ selectedAppearance = store.appState.settingState.appearance
+ }
}
@ViewBuilder
private var formView: some View {
ScrollView {
- SectionItemView("字体大小")
-// .to {}
+ VStack(spacing: 0) {
+ // Dark Mode Section
+ VStack(alignment: .leading, spacing: 12) {
+ Text("主题")
+ .font(.caption)
+ .foregroundColor(.secondaryText)
+ .padding(.horizontal)
+ .padding(.top, 8)
+
+ VStack(spacing: 0) {
+ ForEach(AppearanceMode.allCases, id: \.self) { mode in
+ Button(action: {
+ selectedAppearance = mode
+ dispatch(SettingActions.ChangeAppearanceAction(appearance: mode))
+ }) {
+ HStack {
+ Text(mode.displayName)
+ .foregroundColor(.primaryText)
+ Spacer()
+ if selectedAppearance == mode {
+ Image(systemName: "checkmark")
+ .foregroundColor(.tintColor)
+ .font(.system(size: 14, weight: .semibold))
+ }
+ }
+ .padding(.horizontal)
+ .padding(.vertical, 12)
+ .background(Color.itemBackground)
+ }
+
+ if mode != AppearanceMode.allCases.last {
+ Divider()
+ .padding(.leading)
+ }
+ }
+ }
+ .background(Color.itemBackground)
+ .cornerRadius(10)
+ .padding(.horizontal)
+ }
+ .padding(.top)
+
+ // Font Size Section
+ VStack(alignment: .leading, spacing: 12) {
+ Text("字体")
+ .font(.caption)
+ .foregroundColor(.secondaryText)
+ .padding(.horizontal)
+ .padding(.top, 24)
+
+ SectionItemView("字体大小")
+ .background(Color.itemBackground)
+ .cornerRadius(10)
+ .padding(.horizontal)
+ }
+ }
}
+ .background(Color.background.ignoresSafeArea())
}
}
struct AppearanceSettingView_Previews: PreviewProvider {
static var previews: some View {
- AppearanceSettingView()
+ Group {
+ AppearanceSettingView()
+ .environmentObject(Store.shared)
+ .environment(\.colorScheme, .light)
+
+ AppearanceSettingView()
+ .environmentObject(Store.shared)
+ .environment(\.colorScheme, .dark)
+ }
}
-}
+}
\ No newline at end of file
diff --git a/V2er/View/Settings/SettingsPage.swift b/V2er/View/Settings/SettingsPage.swift
index 5ab607a..932f293 100644
--- a/V2er/View/Settings/SettingsPage.swift
+++ b/V2er/View/Settings/SettingsPage.swift
@@ -22,8 +22,11 @@ struct SettingsPage: View {
private var formView: some View {
ScrollView {
VStack(spacing: 0) {
- SectionItemView("通用设置", showDivider: false)
+ SectionItemView("外观设置", showDivider: false)
.padding(.top, 8)
+ .to { AppearanceSettingView() }
+
+ SectionItemView("通用设置")
.to { OtherSettingsView() }
SectionItemView("帮助与反馈")
@@ -43,7 +46,7 @@ struct SettingsPage: View {
.foregroundColor(Color.tintColor)
Image(systemName: "chevron.right")
.font(.body.weight(.regular))
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
.padding(.trailing, 16)
}
}
diff --git a/V2er/View/Tag/TagDetailPage.swift b/V2er/View/Tag/TagDetailPage.swift
index dcd5aa7..4f00162 100644
--- a/V2er/View/Tag/TagDetailPage.swift
+++ b/V2er/View/Tag/TagDetailPage.swift
@@ -40,7 +40,7 @@ struct TagDetailPage: StateView, InstanceIdentifiable {
}
private var foreGroundColor: Color {
- shouldHideNavbar ? .white.opacity(0.9) : .tintColor
+ shouldHideNavbar ? Color.primaryText.opacity(0.9) : .tintColor
}
private var statusBarStyle: UIStatusBarStyle {
@@ -77,7 +77,7 @@ struct TagDetailPage: StateView, InstanceIdentifiable {
.fade(duration: 0.25)
.resizable()
.blur(radius: 80, opaque: true)
- .overlay(Color.black.opacity(withAnimation {shouldHideNavbar ? 0.3 : 0.1}))
+ .overlay(Color.dynamic(light: .black, dark: .white).opacity(withAnimation {shouldHideNavbar ? 0.3 : 0.1}))
.frame(height: bannerViewHeight * 1.2 + max(scrollY, 0))
Spacer()
}
@@ -206,7 +206,7 @@ struct TagDetailPage: StateView, InstanceIdentifiable {
}
}
}
- .background(.white)
+ .background(Color.itemBackground)
.clipCorner(12, corners: [.topLeft, .topRight])
}
diff --git a/V2er/View/Widget/FlowStack.swift b/V2er/View/Widget/FlowStack.swift
index 178e734..93f9ef4 100644
--- a/V2er/View/Widget/FlowStack.swift
+++ b/V2er/View/Widget/FlowStack.swift
@@ -98,7 +98,7 @@ struct FlowStack_Previews: PreviewProvider {
{
Text($0)
.font(.footnote)
- .foregroundColor(.black)
+ .foregroundColor(.primaryText)
.lineLimit(1)
.padding(.horizontal, 14)
.padding(.vertical, 8)
diff --git a/V2er/View/Widget/NodeView.swift b/V2er/View/Widget/NodeView.swift
index 6c68252..19f8641 100644
--- a/V2er/View/Widget/NodeView.swift
+++ b/V2er/View/Widget/NodeView.swift
@@ -25,11 +25,11 @@ struct NodeView: View {
} label: {
Text(name)
.font(.footnote)
- .foregroundColor(.black)
+ .foregroundColor(Color.dynamic(light: .hex(0x666666), dark: .hex(0xCCCCCC)))
.lineLimit(1)
.padding(.horizontal, 14)
.padding(.vertical, 8)
- .background(Color.lightGray)
+ .background(Color.dynamic(light: Color.hex(0xF5F5F5), dark: Color.hex(0x2C2C2E)))
}
}
diff --git a/V2er/View/Widget/RichTextView/Webview.swift b/V2er/View/Widget/RichTextView/Webview.swift
index b592ea0..9c0c8ce 100644
--- a/V2er/View/Widget/RichTextView/Webview.swift
+++ b/V2er/View/Widget/RichTextView/Webview.swift
@@ -105,25 +105,31 @@ struct Webview : UIViewRepresentable {
}
+ private let lightTextColor = "#1C1C1E"
+ private let darkTextColor = "#F2F2F7"
+
func css(colorScheme: colorScheme) -> String {
+ let imgStyle = "img{max-height: 100%; min-height: 100%; height:auto; max-width: 100%; width:auto;margin-bottom:5px; border-radius: \(imageRadius)px;}"
+ let iframeStyle = "iframe{width:100%; height:250px;}"
+ let textStyleBase = "h1, h2, h3, h4, h5, h6, p, dl, ol, ul, pre, blockquote {text-align:left|right|center; line-height: \(lineHeight)%; font-family: '\(fontName(fontType: self.fontType))'; color: "
+ let importantSuffix = colorImportant == false ? "" : "!important"
+
switch colorScheme {
case .light:
return """
"""
- case .dark :
+ case .dark:
return """
"""
@@ -131,14 +137,14 @@ struct Webview : UIViewRepresentable {
return """
diff --git a/V2er/View/Widget/SectionItemView.swift b/V2er/View/Widget/SectionItemView.swift
index 5fdec03..9688df9 100644
--- a/V2er/View/Widget/SectionItemView.swift
+++ b/V2er/View/Widget/SectionItemView.swift
@@ -27,7 +27,7 @@ struct SectionItemView: View {
SectionView(title, icon: icon, showDivider: showDivider) {
Image(systemName: "chevron.right")
.font(.body.weight(.regular))
- .foregroundColor(.gray)
+ .foregroundColor(.secondaryText)
.padding(.trailing, paddingH)
}
}
@@ -65,6 +65,6 @@ struct SectionView: View {
.padding(.vertical, 17)
.divider(showDivider ? 0.8 : 0.0)
}
- .background(.white)
+ .background(Color.itemBackground)
}
}
diff --git a/V2er/View/Widget/Toast.swift b/V2er/View/Widget/Toast.swift
index 463e48f..dd2ad97 100644
--- a/V2er/View/Widget/Toast.swift
+++ b/V2er/View/Widget/Toast.swift
@@ -44,7 +44,7 @@ struct DefaultToastView: View {
var body: some View {
Label(title, systemImage: icon)
- .foregroundColor(.bodyText)
+ .foregroundColor(.primaryText)
.padding(.horizontal, 20)
.padding(.vertical, 12)
}
@@ -58,9 +58,9 @@ extension View {
self
if isPresented.wrappedValue {
content()
- .visualBlur(bg: .white.opacity(0.95))
+ .background(Color.secondaryBackground.opacity(0.98))
.cornerRadius(99)
- .shadow(color: .black.opacity(0.2), radius: 1.5)
+ .shadow(color: Color.primaryText.opacity(0.3), radius: 3)
.padding(.top, paddingTop)
.transition(AnyTransition.move(edge: .top))
.zIndex(1)
diff --git a/website b/website
index c3bbc04..b5b4f70 160000
--- a/website
+++ b/website
@@ -1 +1 @@
-Subproject commit c3bbc04bb0d0c1f262b1b6e28a464c8b1144e199
+Subproject commit b5b4f70430003ea84edf40eaea25dc484076505a