This commit is contained in:
zeus
2025-01-28 12:28:03 +08:00
parent 738c373a77
commit ec96756800
2534 changed files with 486292 additions and 0 deletions
@@ -0,0 +1,23 @@
import Foundation
import Library
import SwiftUI
@main
struct Application: App {
@UIApplicationDelegateAdaptor private var appDelegate: ApplicationDelegate
@StateObject private var environments = ExtensionEnvironments()
@State private var isLoggedIn = UserManager.shared.isUserLoggedIn()
var body: some Scene {
WindowGroup {
if isLoggedIn {
//MainView().environmentObject(environments)
HomeView(isLoggedIn: $isLoggedIn).environmentObject(environments)
}else{
LoginContentView(isLoggedIn: $isLoggedIn)
}
}
}
}
@@ -0,0 +1,66 @@
import ApplicationLibrary
import Foundation
import Libbox
import Library
import Network
import UIKit
class ApplicationDelegate: NSObject, UIApplicationDelegate {
private var profileServer: ProfileServer?
func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
LibboxSetup(FilePath.sharedDirectory.relativePath, FilePath.workingDirectory.relativePath, FilePath.cacheDirectory.relativePath, false)
setup()
return true
}
private func setup() {
do {
try UIProfileUpdateTask.configure()
NSLog("setup background task success")
} catch {
NSLog("setup background task error: \(error.localizedDescription)")
}
Task {
if UIDevice.current.userInterfaceIdiom == .phone {
await requestNetworkPermission()
}
await setupBackground()
}
}
private nonisolated func setupBackground() async {
if #available(iOS 16.0, *) {
do {
let profileServer = try ProfileServer()
profileServer.start()
await MainActor.run {
self.profileServer = profileServer
}
NSLog("started profile server")
} catch {
NSLog("setup profile server error: \(error.localizedDescription)")
}
}
}
private nonisolated func requestNetworkPermission() async {
if await SharedPreferences.networkPermissionRequested.get() {
return
}
if !DeviceCensorship.isChinaDevice() {
await SharedPreferences.networkPermissionRequested.set(true)
return
}
URLSession.shared.dataTask(with: URL(string: "http://captive.apple.com")!) { _, response, _ in
if let response = response as? HTTPURLResponse {
if response.statusCode == 200 {
Task {
await SharedPreferences.networkPermissionRequested.set(true)
}
}
}
}.resume()
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "10-35-03.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "10-35-15.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "10-35-24.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "11-53-53.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "12-11-56.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "12-14-11.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,11 @@
{
"colors": [
{
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 949 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,158 @@
{
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "57.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "57x57"
},
{
"filename" : "114.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "57x57"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "80.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "50.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "50x50"
},
{
"filename" : "100.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "50x50"
},
{
"filename" : "72.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "72x72"
},
{
"filename" : "144.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "72x72"
},
{
"filename" : "76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.314",
"green" : "0.043",
"red" : "0.106"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.271",
"green" : "0.125",
"red" : "0.161"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "fr.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "germany.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "in.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "si.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "uk.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "us.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.322",
"green" : "0.122",
"red" : "0.192"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.976",
"green" : "0.443",
"red" : "0.816"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.976",
"green" : "0.443",
"red" : "0.816"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.725",
"green" : "0.506",
"red" : "0.553"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.957",
"green" : "0.831",
"red" : "0.400"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,20 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.922",
"green" : "0.427",
"red" : "0.506"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "playstore.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "playstore.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "checkout.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "globe.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.399",
"green" : "0.349",
"red" : "0.353"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.323",
"green" : "0.331",
"red" : "0.350"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.339",
"green" : "0.226",
"red" : "0.255"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.362",
"green" : "0.195",
"red" : "0.339"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "listclipboard.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "cartoon-1298905_1280.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 491 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "message.badge.circle.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "img4.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "playstore.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

@@ -0,0 +1,59 @@
import ApplicationLibrary
import Library
import SwiftUI
struct ContentView: View {
@Environment(\.selection) private var selection
@Environment(\.extensionProfile) private var extensionProfile
var body: some View {
viewBuilder {
if let profile = extensionProfile.wrappedValue {
ContentView0().environmentObject(profile)
} else {
ContentView1()
}
}
}
struct ContentView0: View {
@Environment(\.selection) private var selection
@EnvironmentObject private var extensionProfile: ExtensionProfile
var body: some View {
TabView(selection: selection) {
ForEach(NavigationPage.allCases.filter { it in
it.visible(extensionProfile)
}, id: \.self) { page in
NavigationStackCompat {
page.contentView
}
.tag(page)
.tabItem { page.label }
}
}.onChangeCompat(of: extensionProfile.status) {
if !selection.wrappedValue.visible(extensionProfile) {
selection.wrappedValue = NavigationPage.dashboard
}
}
}
}
struct ContentView1: View {
@Environment(\.selection) private var selection
var body: some View {
TabView(selection: selection) {
ForEach(NavigationPage.allCases.filter { it in
it.visible(nil)
}, id: \.self) { page in
NavigationStackCompat {
page.contentView
}
.tag(page)
.tabItem { page.label }
}
}
}
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"v":"5.12.2","fr":60,"ip":0,"op":72,"w":500,"h":500,"nm":"Lock","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Icon","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,247,0],"ix":2,"l":2},"a":{"a":0,"k":[-81.441,794.705,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[550,550,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":15,"s":[360,360,100]},{"t":30,"s":[550,550,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-2.851,0],[0,-2.851]],"o":[[0,0],[0,0],[0,-2.851],[2.851,0],[0,0]],"v":[[-76.265,790.525],[-86.617,790.525],[-86.617,787.34],[-81.441,782.164],[-76.265,787.34]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.494,-0.366],[0,0],[0.653,0],[0,0.653],[0,0],[0,0.637],[-1.099,0],[0,0],[0,-1.099]],"o":[[0,0],[0,0.653],[-0.653,0],[0,0],[-0.462,-0.366],[0,-1.099],[0,0],[1.099,0],[0,0.653]],"v":[[-80.247,800.065],[-80.247,803.266],[-81.441,804.46],[-82.636,803.266],[-82.636,800.017],[-83.416,798.488],[-81.425,796.497],[-81.409,796.497],[-79.418,798.488]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[2.389,0.366],[0,0],[4.173,0],[0,-4.173],[0,0],[0,-2.755],[0,0],[-3.185,0],[0,0],[0,3.185],[0,0]],"o":[[0,0],[0,-4.173],[-4.173,0],[0,0],[-2.389,0.366],[0,0],[0,3.185],[0,0],[3.185,0],[0,0],[0,-2.755]],"v":[[-73.876,790.62],[-73.876,787.34],[-81.441,779.775],[-89.006,787.34],[-89.006,790.62],[-92.589,795.303],[-92.589,804.859],[-87.812,809.636],[-75.071,809.636],[-70.293,804.859],[-70.293,795.303]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[250,250,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[530,530,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":5,"s":[520,520,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":20,"s":[550,550,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":30,"s":[520,520,100]},{"t":50,"s":[530,530,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-16.335],[16.334,0],[0,16.334],[-16.335,0]],"o":[[0,16.334],[-16.335,0],[0,-16.335],[16.334,0]],"v":[[29.576,0],[0,29.576],[-29.576,0],[0,-29.576]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.29,0.937,0.435,0.5,0.145,0.718,0.437,1,0,0.498,0.439],"ix":9}},"s":{"a":0,"k":[-11.294,-32.337],"ix":5},"e":{"a":0,"k":[9.315,28.16],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
{"v":"5.9.3","fr":29.9700012207031,"ip":0,"op":60.0000024438501,"w":1920,"h":1080,"nm":"1_Loading_Line","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Blue Line","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,539,0],"ix":2,"l":2},"a":{"a":0,"k":[0,-1,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[800,800],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.212477396049,0.540471813725,0.898039215686,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":80,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.1],"y":[1]},"o":{"x":[0.9],"y":[0]},"t":15,"s":[0]},{"t":60.0000024438501,"s":[99.9]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.1],"y":[1]},"o":{"x":[0.9],"y":[0]},"t":0,"s":[0.01]},{"t":45.0000018328876,"s":[100]}],"ix":2},"o":{"a":0,"k":-1,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":150.000006109625,"st":0,"ct":1,"bm":0}],"markers":[{"tm":60.0000024438501,"cm":"END (No Loop)","dr":0}]}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,27 @@
//
// ChatViewControllerWrapper.swift
// SFI
//
// Created by Mac on 2024/10/24.
//
import SwiftUI
import UIKit
import Crisp
// Step 2: Create a SwiftUI wrapper for ChatViewController
struct ChatViewControllerWrapper: UIViewControllerRepresentable {
// Initialize any properties needed to pass to ChatViewController
typealias UIViewControllerType = ChatViewController
func makeUIViewController(context: Context) -> ChatViewController {
// Return the ChatViewController
let chatViewController = ChatViewController()
return chatViewController
}
func updateUIViewController(_ uiViewController: ChatViewController, context: Context) {
// Update the view controller when needed
}
}
@@ -0,0 +1,92 @@
//
// CustomCorners.swift
// CustomCorners
//
// Created by Balaji on 12/09/21.
//
import SwiftUI
struct CustomCorners: Shape {
var radius: CGFloat
var corners: UIRectCorner
func path(in rect: CGRect) -> Path {
let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
return Path(path.cgPath)
}
}
func getSafeAreaInsets() -> UIEdgeInsets {
let windowScene = UIApplication.shared.connectedScenes
.filter({ $0.activationState == .foregroundActive })
.map({ $0 as? UIWindowScene })
.compactMap({ $0 })
.first
guard let keyWindow = windowScene?.windows.filter({ $0.isKeyWindow }).first else {
return .zero
}
return keyWindow.safeAreaInsets
}
func getRect() -> CGRect {
return UIScreen.main.bounds
}
@ViewBuilder
func BackgroundBg()->some View{
ZStack{
LinearGradient(colors: [
Color("BG1"),
Color("BG1"),
Color("BG2"),
Color("BG2"),
], startPoint: .top, endPoint: .bottom)
// Little Planet and little stars....
Image("mars")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 30, height: 30)
.scaleEffect(getRect().height < 750 ? 0.8 : 1)
// not using offset...
// using postiton..
// this will position the object using screen basis...
.position(x: 50, y: getRect().height < 750 ? 200 : 220)
.opacity(0.7)
// Sample star points....
let stars: [CGPoint] = [
CGPoint(x: 15, y: 190),
CGPoint(x: 25, y: 250),
CGPoint(x: 20, y: 350),
CGPoint(x: getRect().width - 30, y: 240),
]
ForEach(stars,id: \.x){star in
Circle()
.fill(.white.opacity(0.3))
.frame(width: 5, height: 5)
.position(star)
.offset(y: getRect().height < 750 ? -20 : 0)
}
Spacer()
}
.ignoresSafeArea()
}
@@ -0,0 +1,33 @@
//
// HTMLTextView.swift
// SFI
//
// Created by Mac on 2024/10/27.
//
import Foundation
import SwiftUI
import UIKit
struct HTMLTextView: UIViewRepresentable {
let htmlString: String
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.isEditable = false
textView.isScrollEnabled = true
textView.backgroundColor = .clear
return textView
}
func updateUIView(_ uiView: UITextView, context: Context) {
guard let data = htmlString.data(using: .utf8) else { return }
do {
let attributedString = try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
uiView.attributedText = attributedString
} catch {
print("Error loading HTML: \(error)")
}
}
}
@@ -0,0 +1,78 @@
//
// CustomTF.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
struct CustomTF: View {
var sfIcon: String
var iconTint: Color = .gray
var hint: String
/// Hides TextField
var isPassword: Bool = false
var hasDriveLine: Bool = true
@Binding var value: String
/// View Properties
@State private var showPassword: Bool = false
/// When Switching Between Hide/Reveal Password Field, The Keyboard is Closing, to avoid that using the FocusState
@FocusState private var passwordState: HideState?
enum HideState {
case hide
case reveal
}
var body: some View {
HStack(alignment: .top, spacing: 8, content: {
Image(systemName: sfIcon)
.foregroundStyle(iconTint)
/// Since I Need Same Width to Align TextFields Equally
.frame(width: 30)
/// Slightly Bringing Down
.offset(y: 2)
VStack(alignment: .leading, spacing: 8, content: {
if isPassword {
Group {
/// Revealing Password when users wants to show Password
if showPassword {
TextField(hint, text: $value)
.focused($passwordState, equals: .reveal)
} else {
SecureField(hint, text: $value)
.focused($passwordState, equals: .hide)
}
}
} else {
TextField(hint, text: $value)
}
if hasDriveLine {
Divider()
}
})
.overlay(alignment: .trailing) {
/// Password Reveal Button
if isPassword {
Button(action: {
withAnimation {
showPassword.toggle()
}
passwordState = showPassword ? .reveal : .hide
}, label: {
Image(systemName: showPassword ? "eye.slash" : "eye")
.foregroundStyle(.gray)
.padding(10)
.contentShape(.rect)
})
}
}
})
}
}
@@ -0,0 +1,28 @@
//
// GradientButton.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
struct GradientButton: View {
var title: String
var icon: String
var onClick: () -> ()
var body: some View {
Button(action: onClick, label: {
HStack(spacing: 15) {
Text(title)
Image(systemName: icon)
}
////.fontWeight(.bold)
.foregroundStyle(.white)
.padding(.vertical, 12)
.padding(.horizontal, 35)
.background(.linearGradient(colors: [.main, .main2, ], startPoint: .top, endPoint: .bottom), in: .capsule)
})
}
}
@@ -0,0 +1,87 @@
//
// OTPVerificationView.swift
// AutoOtpTF
//
// Created by Balaji on 23/12/22.
//
import SwiftUI
struct OTPVerificationView: View {
/// - View Properties
@Binding var otpText: String
/// - Keyboard State
@FocusState private var isKeyboardShowing: Bool
var body: some View {
HStack(spacing: 0){
/// - OTP Text Boxes
/// Change Count Based on your OTP Text Size
ForEach(0..<6,id: \.self){index in
OTPTextBox(index)
}
}
.background(content: {
TextField("", text: $otpText.limit(6))
.keyboardType(.numberPad)
.textContentType(.oneTimeCode)
/// - Hiding it Out
.frame(width: 1, height: 1)
.opacity(0.001)
.blendMode(.screen)
.focused($isKeyboardShowing)
})
.contentShape(Rectangle())
/// - Opening Keyboard When Tapped
.onTapGesture {
isKeyboardShowing = true
}
.toolbar {
ToolbarItem(placement: .keyboard) {
Button("Done"){
isKeyboardShowing = false
}
.tint(.white)
////.fontWeight(.heavy)
.hSpacing(.trailing)
}
}
}
// MARK: OTP Text Box
@ViewBuilder
func OTPTextBox(_ index: Int)->some View{
ZStack{
if otpText.count > index{
/// - Finding Char At Index
let startIndex = otpText.startIndex
let charIndex = otpText.index(startIndex, offsetBy: index)
let charToString = String(otpText[charIndex])
Text(charToString)
}else{
Text(" ")
}
}
.frame(width: 45, height: 45)
.background {
/// - Highlighting Current Active Box
let status = (isKeyboardShowing && otpText.count == index)
RoundedRectangle(cornerRadius: 6, style: .continuous)
.stroke(status ? .main : Color.gray,lineWidth: status ? 3 : 0.5)
/// - Adding Animation
.animation(.easeInOut(duration: 0.2), value: isKeyboardShowing)
}
.frame(maxWidth: .infinity)
}
}
// MARK: Binding <String> Extension
extension Binding where Value == String{
func limit(_ length: Int)->Self{
if self.wrappedValue.count > length{
DispatchQueue.main.async {
self.wrappedValue = String(self.wrappedValue.prefix(length))
}
}
return self
}
}
@@ -0,0 +1,31 @@
//
// LottieView.swift
// VPNUI
//
// Created by Mac on 2024/9/26.
//
import Foundation
//import Lottie
import SwiftUI
import Lottie
struct LottieView: UIViewRepresentable {
var animationFileName: String
let loopMode: LottieLoopMode
func updateUIView(_ uiView: UIViewType, context: Context) {
}
func makeUIView(context: Context) -> Lottie.LottieAnimationView {
let animationView = LottieAnimationView(name: animationFileName)
animationView.loopMode = loopMode
animationView.play()
animationView.contentMode = .scaleAspectFit
return animationView
}
}
@@ -0,0 +1,20 @@
//
// Unitity.swift
// SFI
//
// Created by Mac on 2024/10/20.
//
import Foundation
struct TimestampConverter {
// Function to convert a timestamp to a formatted date string
static func convertTimestampToDateString(_ timestamp: Int, format: String = "yyyy-MM-dd HH:mm:ss") -> String {
let timeInterval = TimeInterval(timestamp)
let date = Date(timeIntervalSince1970: timeInterval)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: date)
}
}
@@ -0,0 +1,93 @@
//
// UniversalAlert.swift
// CustomUniversalAlert
//
// Created by Balaji Venkatesh on 18/09/23.
//
import SwiftUI
/// Alert Config
struct AlertConfig {
fileprivate var enableBackgroundBlur: Bool = true
fileprivate var disableOutsideTap: Bool = true
fileprivate var transitionType: TransitionType = .slide
fileprivate var slideEdge: Edge = .bottom
fileprivate var show: Bool = false
fileprivate var showView: Bool = false
init(enableBackgroundBlur: Bool = true, disableOutsideTap: Bool = true, transitionType: TransitionType = .slide, slideEdge: Edge = .bottom) {
self.enableBackgroundBlur = enableBackgroundBlur
self.disableOutsideTap = disableOutsideTap
self.transitionType = transitionType
self.slideEdge = slideEdge
}
/// TransitionType
enum TransitionType {
case slide
case opacity
}
/// Alert Present/Dismiss Methods
mutating
func present() {
show = true
}
mutating
func dismiss() {
show = false
}
}
fileprivate struct AlertView<Content: View>: View {
@Binding var config: AlertConfig
/// View Tag
var tag: Int
@ViewBuilder var content: () -> Content
/// View Properties
@State private var showView: Bool = false
var body: some View {
GeometryReader(content: { geometry in
if showView && config.transitionType == .slide {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.move(edge: config.slideEdge))
} else {
content()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.opacity(showView ? 1 : 0)
}
})
.background {
ZStack {
if config.enableBackgroundBlur {
Rectangle()
.fill(.ultraThinMaterial)
} else {
Rectangle()
.fill(.primary.opacity(0.25))
}
}
.ignoresSafeArea()
.contentShape(.rect)
.onTapGesture {
if !config.disableOutsideTap {
config.dismiss()
}
}
.opacity(showView ? 1 : 0)
}
.onAppear(perform: {
config.showView = true
})
// .onChange(of: config.showView) { oldValue, newValue in
// withAnimation(.smooth(duration: 0.35, extraBounce: 0)) {
// showView = newValue
// }
// }
}
}
@@ -0,0 +1,190 @@
//
// View+Extensions.swift
// LoginKit
//
// Created by Balaji on 04/08/23.
//
import SwiftUI
/// Custom SwiftUI View Extensions
extension View {
/// View Alignments
@ViewBuilder
func hSpacing(_ alignment: Alignment = .center) -> some View {
self
.frame(maxWidth: .infinity, alignment: alignment)
}
@ViewBuilder
func vSpacing(_ alignment: Alignment = .center) -> some View {
self
.frame(maxHeight: .infinity, alignment: alignment)
}
/// Disable With Opacity
@ViewBuilder
func disableWithOpacity(_ condition: Bool) -> some View {
self
.disabled(condition)
.opacity(condition ? 0.5 : 1)
}
}
// Extedning View to get Screen Size and Frame....
extension View{
func getRect()->CGRect{
UIScreen.main.bounds
}
func getSafeArea()->UIEdgeInsets{
guard let screen = UIApplication.shared.connectedScenes.first as? UIWindowScene else{
return .zero
}
guard let safeArea = screen.windows.first?.safeAreaInsets else{
return .zero
}
return safeArea
}
}
extension Text {
init(_ attributedString: NSAttributedString) {
self.init("") // initial, empty Text
// scan the attributed string for distinctly attributed regions
attributedString.enumerateAttributes(in: NSRange(location: 0, length: attributedString.length),
options: []) { (attrs, range, _) in
let string = attributedString.attributedSubstring(from: range).string
var text = Text(string)
// then, read applicable attributes and apply them to the Text
if let font = attrs[.font] as? UIFont {
// this takes care of the majority of formatting - text size, font family,
// font weight, if it's italic, etc.
text = text.font(.init(font))
}
if let color = attrs[.foregroundColor] as? UIColor {
text = text.foregroundColor(Color(color))
}
if let kern = attrs[.kern] as? CGFloat {
text = text.kerning(kern)
}
if #available(iOS 14.0, *) {
if let tracking = attrs[.tracking] as? CGFloat {
text = text.tracking(tracking)
}
}
if let strikethroughStyle = attrs[.strikethroughStyle] as? NSNumber,
strikethroughStyle != 0 {
if let strikethroughColor = (attrs[.strikethroughColor] as? UIColor) {
text = text.strikethrough(true, color: Color(strikethroughColor))
} else {
text = text.strikethrough(true)
}
}
if let underlineStyle = attrs[.underlineStyle] as? NSNumber,
underlineStyle != 0 {
if let underlineColor = (attrs[.underlineColor] as? UIColor) {
text = text.underline(true, color: Color(underlineColor))
} else {
text = text.underline(true)
}
}
if let baselineOffset = attrs[.baselineOffset] as? NSNumber {
text = text.baselineOffset(CGFloat(baselineOffset.floatValue))
}
// append the newly styled subtext to the rest of the text
self = self + text
}
}
}
extension Text {
init(html htmlString: String, // the HTML-formatted string
raw: Bool = false, // set to true if you don't want to embed in the doc skeleton
size: CGFloat? = nil, // optional document-wide text size
fontFamily: String = "-apple-system") { // optional document-wide font family
let fullHTML: String
if raw {
fullHTML = htmlString
} else {
var sizeCss = ""
if let size = size {
sizeCss = "font-size: \(size)px;"
}
fullHTML = """
<!doctype html>
<html>
<head>
<style>
body {
font-family: \(fontFamily);
\(sizeCss)
}
</style>
</head>
<body>
\(htmlString)
</body>
</html>
"""
}
let attributedString: NSAttributedString
if let data = fullHTML.data(using: .unicode),
let attrString = try? NSAttributedString(data: data,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil) {
attributedString = attrString
} else {
attributedString = NSAttributedString()
}
self.init(attributedString) // uses the NSAttributedString initializer
}
}
public extension View {
// View
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
func transparentScrolling() -> some View {
if #available(iOS 16.0, *) {
return scrollContentBackground(.hidden)
} else {
return onAppear {
UITextView.appearance().backgroundColor = .clear
}
}
}
}
struct TriangleShape: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: rect.minX, y: rect.minY))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
path.closeSubpath()
return path
}
}

Some files were not shown because too many files have changed in this diff Show More