Skip to content

Commit

Permalink
Merge pull request #164 from fkunn1326/main
Browse files Browse the repository at this point in the history
Add some improvements for hiding/locking apps
  • Loading branch information
hugeBlack authored Sep 25, 2024
2 parents 6574fdd + 584c36e commit 1b870ee
Show file tree
Hide file tree
Showing 10 changed files with 220 additions and 50 deletions.
53 changes: 53 additions & 0 deletions LiveContainerSwiftUI/LCAppBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ struct LCAppBanner : View {
Capsule().fill(Color("JITBadgeColor"))
)
}
if model.uiIsLocked && !model.uiIsHidden {
Text("lc.appBanner.locked".loc).font(.system(size: 8)).bold().padding(2)
.frame(width: 50, height:16)
.background(
Capsule().fill(Color("BadgeColor"))
)
}
}

Text("\(appInfo.version()) - \(appInfo.bundleIdentifier())").font(.system(size: 12)).foregroundColor(Color("FontColor"))
Expand Down Expand Up @@ -239,6 +246,18 @@ struct LCAppBanner : View {
}

func runApp() async {
if appInfo.isLocked && !sharedModel.isHiddenAppUnlocked {
do {
if !(try await LCUtils.authenticateUser()) {
return
}
} catch {
errorInfo = error.localizedDescription
errorShow = true
return
}
}

do {
try await model.runApp()
} catch {
Expand Down Expand Up @@ -319,3 +338,37 @@ struct LCAppBanner : View {


}


struct LCAppSkeletonBanner: View {
var body: some View {
HStack {
RoundedRectangle(cornerRadius: 12)
.fill(Color.gray.opacity(0.3))
.frame(width: 60, height: 60)

VStack(alignment: .leading, spacing: 5) {
RoundedRectangle(cornerRadius: 4)
.fill(Color.gray.opacity(0.3))
.frame(width: 100, height: 16)

RoundedRectangle(cornerRadius: 4)
.fill(Color.gray.opacity(0.3))
.frame(width: 150, height: 12)

RoundedRectangle(cornerRadius: 4)
.fill(Color.gray.opacity(0.3))
.frame(width: 120, height: 8)
}

Spacer()

RoundedRectangle(cornerRadius: 16)
.fill(Color.gray.opacity(0.3))
.frame(width: 70, height: 32)
}
.padding()
.frame(height: 88)
.background(RoundedRectangle(cornerRadius: 22).fill(Color.gray.opacity(0.1)))
}
}
92 changes: 59 additions & 33 deletions LiveContainerSwiftUI/LCAppListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
@State private var isNavigationActive = false

@EnvironmentObject private var sharedModel : SharedModel

init(apps: Binding<[LCAppModel]>, hiddenApps: Binding<[LCAppModel]>, appDataFolderNames: Binding<[String]>, tweakFolderNames: Binding<[String]>) {
_installOptions = State(initialValue: [])
_apps = apps
Expand Down Expand Up @@ -95,38 +95,61 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
}
.padding()
.animation(.easeInOut, value: apps)

if !sharedModel.isHiddenAppUnlocked {
Text(apps.count > 0 ? "lc.appList.appCounter %lld".localizeWithFormat(apps.count) : "lc.appList.installTip".loc).foregroundStyle(.gray)
.onTapGesture(count: 3) {
Task { await authenticateUser() }
}
}


if sharedModel.isHiddenAppUnlocked {
LazyVStack {
HStack {
Text("lc.appList.hiddenApps".loc)
.font(.system(.title2).bold())
.border(Color.black)
Spacer()
VStack {
if LCUtils.appGroupUserDefault.bool(forKey: "LCStrictHiding") {
if sharedModel.isHiddenAppUnlocked {
LazyVStack {
HStack {
Text("lc.appList.hiddenApps".loc)
.font(.system(.title2).bold())
Spacer()
}
ForEach(hiddenApps, id: \.self) { app in
LCAppBanner(appModel: app, delegate: self, appDataFolders: $appDataFolderNames, tweakFolders: $tweakFolderNames)
}
}
.padding()
.transition(.opacity)
.animation(.easeInOut, value: apps)

if hiddenApps.count == 0 {
Text("lc.appList.hideAppTip".loc)
.foregroundStyle(.gray)
}
}
ForEach(hiddenApps, id: \.self) { app in
LCAppBanner(appModel: app, delegate: self, appDataFolders: $appDataFolderNames, tweakFolders: $tweakFolderNames)
} else if hiddenApps.count > 0 {
LazyVStack {
HStack {
Text("lc.appList.hiddenApps".loc)
.font(.system(.title2).bold())
Spacer()
}
ForEach(hiddenApps, id: \.self) { app in
if sharedModel.isHiddenAppUnlocked {
LCAppBanner(appModel: app, delegate: self, appDataFolders: $appDataFolderNames, tweakFolders: $tweakFolderNames)
} else {
LCAppSkeletonBanner()
}
}
.animation(.easeInOut, value: sharedModel.isHiddenAppUnlocked)
.onTapGesture {
Task { await authenticateUser() }
}
}
.transition(.scale)
.padding()
.animation(.easeInOut, value: apps)
}
.padding()
.animation(.easeInOut, value: apps)

if hiddenApps.count == 0 {
Text("lc.appList.hideAppTip".loc)
.foregroundStyle(.gray)
}
Text(apps.count + hiddenApps.count > 0 ? "lc.appList.appCounter %lld".localizeWithFormat(apps.count + hiddenApps.count) : "lc.appList.installTip".loc).foregroundStyle(.gray)
}

let appCount = sharedModel.isHiddenAppUnlocked ? apps.count + hiddenApps.count : apps.count
Text(appCount > 0 ? "lc.appList.appCounter %lld".localizeWithFormat(appCount) : "lc.appList.installTip".loc)
.foregroundStyle(.gray)
.animation(.easeInOut, value: appCount)
.onTapGesture(count: 3) {
Task { await authenticateUser() }
}
}.animation(.easeInOut, value: LCUtils.appGroupUserDefault.bool(forKey: "LCStrictHiding"))

if LCUtils.multiLCStatus == 2 {
Text("lc.appList.manageInPrimaryTip".loc).foregroundStyle(.gray).padding()
}
Expand Down Expand Up @@ -272,7 +295,7 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
return
}

if appToLaunch.appInfo.isHidden && !sharedModel.isHiddenAppUnlocked {
if appToLaunch.appInfo.isLocked && !sharedModel.isHiddenAppUnlocked {
do {
if !(try await LCUtils.authenticateUser()) {
return
Expand Down Expand Up @@ -460,24 +483,27 @@ struct LCAppListView : View, LCAppBannerDelegate, LCAppModelDelegate {
return
}
var appFound : LCAppModel? = nil
var isFoundAppHidden = false
var isFoundAppLocked = false
for app in apps {
if app.appInfo.relativeBundlePath == bundleId {
appFound = app
if app.appInfo.isLocked {
isFoundAppLocked = true
}
break
}
}
if appFound == nil && !LCUtils.appGroupUserDefault.bool(forKey: "LCStrictHiding") {
for app in hiddenApps {
if app.appInfo.relativeBundlePath == bundleId {
appFound = app
isFoundAppHidden = true
isFoundAppLocked = true
break
}
}
}

if isFoundAppHidden && !sharedModel.isHiddenAppUnlocked {
if isFoundAppLocked && !sharedModel.isHiddenAppUnlocked {
do {
let result = try await LCUtils.authenticateUser()
if !result {
Expand Down
20 changes: 20 additions & 0 deletions LiveContainerSwiftUI/LCAppModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class LCAppModel: ObservableObject, Hashable {

@Published var uiIsJITNeeded : Bool
@Published var uiIsHidden : Bool
@Published var uiIsLocked : Bool
@Published var uiIsShared : Bool
@Published var uiDataFolder : String?
@Published var uiTweakFolder : String?
Expand All @@ -29,9 +30,14 @@ class LCAppModel: ObservableObject, Hashable {
init(appInfo : LCAppInfo, delegate: LCAppModelDelegate? = nil) {
self.appInfo = appInfo
self.delegate = delegate

if !appInfo.isLocked && appInfo.isHidden {
appInfo.isLocked = true
}

self.uiIsJITNeeded = appInfo.isJITNeeded
self.uiIsHidden = appInfo.isHidden
self.uiIsLocked = appInfo.isLocked
self.uiIsShared = appInfo.isShared
self.uiDataFolder = appInfo.getDataUUIDNoAssign()
self.uiTweakFolder = appInfo.tweakFolder()
Expand Down Expand Up @@ -121,6 +127,20 @@ class LCAppModel: ObservableObject, Hashable {
LCUtils.launchToGuestApp()

}

func toggleLock() async {
if appInfo.isLocked {
appInfo.isLocked = false
uiIsLocked = false

if appInfo.isHidden {
await toggleHidden()
}
} else {
appInfo.isLocked = true
uiIsLocked = true
}
}

func toggleHidden() async {
delegate?.closeNavigationView()
Expand Down
37 changes: 31 additions & 6 deletions LiveContainerSwiftUI/LCAppSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,45 @@ struct LCAppSettingsView : View{
} footer: {
Text("lc.appSettings.launchWithJitDesc".loc)
}

if sharedModel.isHiddenAppUnlocked {
Section {

Section {
Toggle(isOn: $model.uiIsLocked) {
Text("lc.appSettings.lockApp".loc)
}
.onChange(of: model.uiIsLocked, perform: { newValue in
Task {
if !newValue {
do {
let result = try await LCUtils.authenticateUser()
if !result {
model.uiIsLocked = true
return
}
} catch {
return
}
}

await model.toggleLock()
}
})

if model.uiIsLocked {
Toggle(isOn: $model.uiIsHidden) {
Text("lc.appSettings.hideApp".loc)
}
.onChange(of: model.uiIsHidden, perform: { newValue in
.onChange(of: model.uiIsHidden, perform: { _ in
Task { await toggleHidden() }
})
} footer: {
.transition(.opacity.combined(with: .slide))
}
} footer: {
if model.uiIsLocked {
Text("lc.appSettings.hideAppDesc".loc)
.transition(.opacity.combined(with: .slide))
}

}


Section {
Toggle(isOn: $model.uiDoSymlinkInbox) {
Expand Down
12 changes: 5 additions & 7 deletions LiveContainerSwiftUI/LCSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,12 @@ struct LCSettingsView: View {
Text("lc.settings.injectLCItselfDesc".loc)
}

if sharedModel.isHiddenAppUnlocked {
Section {
Toggle(isOn: $strictHiding) {
Text("lc.settings.strictHiding".loc)
}
} footer: {
Text("lc.settings.strictHidingDesc".loc)
Section {
Toggle(isOn: $strictHiding) {
Text("lc.settings.strictHiding".loc)
}
} footer: {
Text("lc.settings.strictHidingDesc".loc)
}

Section {
Expand Down
4 changes: 2 additions & 2 deletions LiveContainerSwiftUI/LCWebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ struct LCWebView: View {
return
}

if appToLaunch.appInfo.isHidden && !sharedModel.isHiddenAppUnlocked {
if appToLaunch.appInfo.isLocked && !sharedModel.isHiddenAppUnlocked {

do {
if !(try await LCUtils.authenticateUser()) {
Expand Down Expand Up @@ -214,7 +214,7 @@ struct LCWebView: View {
return
}

if appToLaunch.appInfo.isHidden && !sharedModel.isHiddenAppUnlocked {
if appToLaunch.appInfo.isLocked && !sharedModel.isHiddenAppUnlocked {
do {
if !(try await LCUtils.authenticateUser()) {
return
Expand Down
34 changes: 34 additions & 0 deletions LiveContainerSwiftUI/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,23 @@
}
}
},
"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 @@ -790,6 +807,23 @@
}
}
},
"lc.appSettings.lockApp" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Lock App"
}
},
"zh_CN" : {
"stringUnit" : {
"state" : "translated",
"value" : "锁定App"
}
}
}
},
"lc.appSettings.hideApp" : {
"extractionState" : "manual",
"localizations" : {
Expand Down
1 change: 1 addition & 0 deletions LiveContainerUI/LCAppInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@property NSString* relativeBundlePath;
@property bool isShared;
@property bool isJITNeeded;
@property bool isLocked;
@property bool isHidden;
@property bool doSymlinkInbox;
@property bool bypassAssertBarrierOnQueue;
Expand Down
Loading

0 comments on commit 1b870ee

Please sign in to comment.