Skip to content

Commit

Permalink
Merge pull request #192 from slds1/main
Browse files Browse the repository at this point in the history
extract colors from app icons
  • Loading branch information
hugeBlack authored Oct 23, 2024
2 parents e5cf20b + ae2e355 commit 8978b6b
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 38 deletions.
58 changes: 52 additions & 6 deletions LiveContainerSwiftUI/LCAppBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Foundation
import SwiftUI
import UniformTypeIdentifiers
import UIKit

protocol LCAppBannerDelegate {
func removeApp(app: LCAppModel)
Expand All @@ -33,6 +34,7 @@ struct LCAppBanner : View {

@State private var errorShow = false
@State private var errorInfo = ""
@AppStorage("dynamicColors") var dynamicColors = true

@EnvironmentObject private var sharedModel : SharedModel

Expand All @@ -44,6 +46,7 @@ struct LCAppBanner : View {

_model = ObservedObject(wrappedValue: appModel)
}
@State private var mainHueColor: CGFloat? = nil

var body: some View {

Expand Down Expand Up @@ -81,8 +84,8 @@ struct LCAppBanner : View {
}
}

Text("\(appInfo.version()) - \(appInfo.bundleIdentifier())").font(.system(size: 12)).foregroundColor(Color("FontColor"))
Text(LocalizedStringKey(model.uiDataFolder == nil ? "lc.appBanner.noDataFolder".loc : model.uiDataFolder!)).font(.system(size: 8)).foregroundColor(Color("FontColor"))
Text("\(appInfo.version()) - \(appInfo.bundleIdentifier())").font(.system(size: 12)).foregroundColor(dynamicColors ? extractMainHueColor(from: appInfo.icon()) : Color("FontColor"))
Text(LocalizedStringKey(model.uiDataFolder == nil ? "lc.appBanner.noDataFolder".loc : model.uiDataFolder!)).font(.system(size: 8)).foregroundColor(dynamicColors ? extractMainHueColor(from: appInfo.icon()) : Color("FontColor"))
})
}
Spacer()
Expand All @@ -102,14 +105,14 @@ struct LCAppBanner : View {
.fixedSize()
.background(GeometryReader { g in
if !model.isSigningInProgress {
Capsule().fill(Color("FontColor"))
Capsule().fill(dynamicColors ? extractMainHueColor(from: appInfo.icon()) : Color("FontColor"))
} else {
let w = g.size.width
let h = g.size.height
Capsule()
.fill(Color("FontColor")).opacity(0.2)
.fill(dynamicColors ? extractMainHueColor(from: appInfo.icon()) : Color("FontColor")).opacity(0.2)
Circle()
.fill(Color("FontColor"))
.fill(dynamicColors ? extractMainHueColor(from: appInfo.icon()) : Color("FontColor"))
.frame(width: w * 2, height: w * 2)
.offset(x: (model.signProgress - 2) * w, y: h/2-w)
}
Expand All @@ -121,7 +124,7 @@ struct LCAppBanner : View {
}
.padding()
.frame(height: 88)
.background(RoundedRectangle(cornerSize: CGSize(width:22, height: 22)).fill(Color("AppBannerBG")))
.background(RoundedRectangle(cornerSize: CGSize(width:22, height: 22)).fill(dynamicColors ? extractMainHueColor(from: appInfo.icon()).opacity(0.5) : Color("AppBannerBG")))
.onAppear() {
handleOnAppear()
}
Expand Down Expand Up @@ -337,6 +340,47 @@ struct LCAppBanner : View {
self.saveIconExporterShow = true
}

func extractMainHueColor(from image: UIImage) -> Color {
guard let cgImage = image.cgImage else { return Color.clear }

let width = 1
let height = 1
let bitmapInfo = CGImageAlphaInfo.premultipliedLast.rawValue
let colorSpace = CGColorSpaceCreateDeviceRGB()
var pixelData = [UInt8](repeating: 0, count: 4)

guard let context = CGContext(data: &pixelData, width: width, height: height, bitsPerComponent: 8, bytesPerRow: 4, space: colorSpace, bitmapInfo: bitmapInfo) else {
return Color.clear
}

context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

let red = CGFloat(pixelData[0]) / 255.0
let green = CGFloat(pixelData[1]) / 255.0
let blue = CGFloat(pixelData[2]) / 255.0

let averageColor = UIColor(red: red, green: green, blue: blue, alpha: 1.0)

var hue: CGFloat = 0
var saturation: CGFloat = 0
var brightness: CGFloat = 0
var alpha: CGFloat = 0
averageColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)

if brightness < 0.1 && saturation < 0.1 {
return Color.red
}

if brightness < 0.3 {
brightness = 0.3
}

return Color(hue: hue, saturation: saturation, brightness: brightness)
}





}

Expand Down Expand Up @@ -372,4 +416,6 @@ struct LCAppSkeletonBanner: View {
.frame(height: 88)
.background(RoundedRectangle(cornerRadius: 22).fill(Color.gray.opacity(0.1)))
}

}

10 changes: 10 additions & 0 deletions LiveContainerSwiftUI/LCSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct LCSettingsView: View {
@State var silentSwitchApp = false
@State var injectToLCItelf = false
@State var strictHiding = false
@AppStorage("dynamicColors") var dynamicColors = true

@State var sideJITServerAddress : String
@State var deviceUDID: String
Expand Down Expand Up @@ -152,6 +153,15 @@ struct LCSettingsView: View {
Text("lc.settings.JitDesc".loc)
}

Section{
Toggle(isOn: $dynamicColors) {
Text("lc.settings.dynamicColors".loc)
}
} header: {
Text("lc.settings.interface".loc)
} footer: {
Text("lc.settings.dynamicColors.desc".loc)
}
Section{
Toggle(isOn: $frameShortIcon) {
Text("lc.settings.FrameIcon".loc)
Expand Down
97 changes: 65 additions & 32 deletions LiveContainerSwiftUI/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@
}
}
},
"lc.appBanner.locked" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "LOCKED"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定"
}
}
}
},
"lc.appBanner.noDataFolder" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -222,23 +239,6 @@
}
}
},
"lc.appBanner.locked" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "LOCKED"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定"
}
}
}
},
"lc.appBanner.uninstall" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -807,87 +807,87 @@
}
}
},
"lc.appSettings.lockApp" : {
"lc.appSettings.hideApp" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lock App"
"value" : "Hide App"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定App"
"value" : "隐藏App"
}
}
}
},
"lc.appSettings.hideApp" : {
"lc.appSettings.hideAppDesc" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Hide App"
"value" : "To completely hide apps, enable Strict Hiding mode in settings."
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "隐藏App"
"value" : "要完全隐藏App,请在设置中启用严格隐藏模式。"
}
}
}
},
"lc.appSettings.hideAppDesc" : {
"lc.appSettings.launchWithJit" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "To completely hide apps, enable Strict Hiding mode in settings."
"value" : "Launch with JIT"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "要完全隐藏App,请在设置中启用严格隐藏模式。"
"value" : "带JIT启动"
}
}
}
},
"lc.appSettings.launchWithJit" : {
"lc.appSettings.launchWithJitDesc" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Launch with JIT"
"value" : "LiveContainer will try to acquire JIT permission before launching the app."
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "带JIT启动"
"value" : "在启动App前LiveContainer会尝试获取JIT权限。"
}
}
}
},
"lc.appSettings.launchWithJitDesc" : {
"lc.appSettings.lockApp" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "LiveContainer will try to acquire JIT permission before launching the app."
"value" : "Lock App"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "在启动App前LiveContainer会尝试获取JIT权限。"
"value" : "锁定App"
}
}
}
Expand Down Expand Up @@ -1647,6 +1647,28 @@
}
}
},
"lc.settings.dynamicColors" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dynamic colors"
}
}
}
},
"lc.settings.dynamicColors.desc" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Enable dynamic colors for app boxes"
}
}
}
},
"lc.settings.error.altstoreNotPatched" : {
"extractionState" : "manual",
"localizations" : {
Expand Down Expand Up @@ -1766,6 +1788,17 @@
}
}
},
"lc.settings.interface" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "interface"
}
}
}
},
"lc.settings.JitAddress" : {
"extractionState" : "manual",
"localizations" : {
Expand Down

0 comments on commit 8978b6b

Please sign in to comment.