diff --git a/dmg.sh b/dmg.sh new file mode 100755 index 0000000..a750d4c --- /dev/null +++ b/dmg.sh @@ -0,0 +1,3 @@ +#! /bin/sh + +create-dmg --volname "punchnet" --window-pos 200 120 --window-size 800 400 --icon "punchnet.app" 200 190 --hide-extension "punchnet.app" --app-drop-link 600 185 ~/Desktop/punchnet.dmg /Users/anlicheng/Desktop/sdlan_v1 diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/Contents.json b/punchnet/Assets.xcassets/AppIcon.appiconset/Contents.json index 3f00db4..6c69d1c 100644 --- a/punchnet/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/punchnet/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,46 +1,55 @@ { "images" : [ { + "filename" : "logo.png", "idiom" : "mac", "scale" : "1x", "size" : "16x16" }, { + "filename" : "logo_32.png", "idiom" : "mac", "scale" : "2x", "size" : "16x16" }, { + "filename" : "logo_32 1.png", "idiom" : "mac", "scale" : "1x", "size" : "32x32" }, { + "filename" : "logo_64.png", "idiom" : "mac", "scale" : "2x", "size" : "32x32" }, { + "filename" : "logo_128.png", "idiom" : "mac", "scale" : "1x", "size" : "128x128" }, { + "filename" : "logo_256.png", "idiom" : "mac", "scale" : "2x", "size" : "128x128" }, { + "filename" : "logo_256 1.png", "idiom" : "mac", "scale" : "1x", "size" : "256x256" }, { + "filename" : "logo_512.png", "idiom" : "mac", "scale" : "2x", "size" : "256x256" }, { + "filename" : "logo_512 1.png", "idiom" : "mac", "scale" : "1x", "size" : "512x512" diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo.png new file mode 100644 index 0000000..cd751e5 Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_128.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_128.png new file mode 100644 index 0000000..65f1ab2 Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_128.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256 1.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256 1.png new file mode 100644 index 0000000..61895ca Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256 1.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256.png new file mode 100644 index 0000000..61895ca Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_256.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32 1.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32 1.png new file mode 100644 index 0000000..14a197d Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32 1.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32.png new file mode 100644 index 0000000..14a197d Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_32.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512 1.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512 1.png new file mode 100644 index 0000000..ca03b0b Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512 1.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512.png new file mode 100644 index 0000000..ca03b0b Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_512.png differ diff --git a/punchnet/Assets.xcassets/AppIcon.appiconset/logo_64.png b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_64.png new file mode 100644 index 0000000..336705f Binary files /dev/null and b/punchnet/Assets.xcassets/AppIcon.appiconset/logo_64.png differ diff --git a/punchnet/Assets.xcassets/IosSettings.imageset/Contents.json b/punchnet/Assets.xcassets/IosSettings.imageset/Contents.json new file mode 100644 index 0000000..86b7504 --- /dev/null +++ b/punchnet/Assets.xcassets/IosSettings.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "IosSettings.svg", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/punchnet/Assets.xcassets/IosSettings.imageset/IosSettings.svg b/punchnet/Assets.xcassets/IosSettings.imageset/IosSettings.svg new file mode 100644 index 0000000..407f120 --- /dev/null +++ b/punchnet/Assets.xcassets/IosSettings.imageset/IosSettings.svg @@ -0,0 +1,8 @@ + diff --git a/punchnet/Assets.xcassets/close.imageset/Contents.json b/punchnet/Assets.xcassets/close.imageset/Contents.json new file mode 100644 index 0000000..acb0efb --- /dev/null +++ b/punchnet/Assets.xcassets/close.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "close.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/punchnet/Assets.xcassets/close.imageset/close.png b/punchnet/Assets.xcassets/close.imageset/close.png new file mode 100644 index 0000000..28c985f Binary files /dev/null and b/punchnet/Assets.xcassets/close.imageset/close.png differ diff --git a/punchnet/Assets.xcassets/line.imageset/Contents.json b/punchnet/Assets.xcassets/line.imageset/Contents.json new file mode 100644 index 0000000..25625b1 --- /dev/null +++ b/punchnet/Assets.xcassets/line.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "line.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/punchnet/Assets.xcassets/line.imageset/line.png b/punchnet/Assets.xcassets/line.imageset/line.png new file mode 100644 index 0000000..0f80d59 Binary files /dev/null and b/punchnet/Assets.xcassets/line.imageset/line.png differ diff --git a/punchnet/Assets.xcassets/logo.imageset/Contents.json b/punchnet/Assets.xcassets/logo.imageset/Contents.json index 769bacf..911faf2 100644 --- a/punchnet/Assets.xcassets/logo.imageset/Contents.json +++ b/punchnet/Assets.xcassets/logo.imageset/Contents.json @@ -1,7 +1,6 @@ { "images" : [ { - "filename" : "logo.jpg", "idiom" : "universal", "scale" : "1x" }, @@ -12,6 +11,15 @@ { "idiom" : "universal", "scale" : "3x" + }, + { + "filename" : "logo.png", + "idiom" : "mac", + "scale" : "1x" + }, + { + "idiom" : "mac", + "scale" : "2x" } ], "info" : { diff --git a/punchnet/Assets.xcassets/logo.imageset/logo.jpg b/punchnet/Assets.xcassets/logo.imageset/logo.jpg deleted file mode 100644 index ce597f5..0000000 Binary files a/punchnet/Assets.xcassets/logo.imageset/logo.jpg and /dev/null differ diff --git a/punchnet/Assets.xcassets/logo.imageset/logo.png b/punchnet/Assets.xcassets/logo.imageset/logo.png new file mode 100644 index 0000000..8779191 Binary files /dev/null and b/punchnet/Assets.xcassets/logo.imageset/logo.png differ diff --git a/punchnet/Assets.xcassets/logo_32.imageset/Contents.json b/punchnet/Assets.xcassets/logo_32.imageset/Contents.json new file mode 100644 index 0000000..e0a8e34 --- /dev/null +++ b/punchnet/Assets.xcassets/logo_32.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "logo_32.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/punchnet/Assets.xcassets/logo_32.imageset/logo_32.png b/punchnet/Assets.xcassets/logo_32.imageset/logo_32.png new file mode 100644 index 0000000..14a197d Binary files /dev/null and b/punchnet/Assets.xcassets/logo_32.imageset/logo_32.png differ diff --git a/punchnet/ContentView.swift b/punchnet/ContentView.swift index 3b29c91..baeab9f 100644 --- a/punchnet/ContentView.swift +++ b/punchnet/ContentView.swift @@ -10,67 +10,154 @@ import SwiftData import Combine struct ContentView: View { - //@Environment(\.modelContext) private var modelContext - //@Query private var items: [Item] @AppStorage("token") private var token: String = "" + @State private var showToken: Bool = false + @ObservedObject private var vpnManager = VPNManager.shared @State private var showAlert = false @State private var showStunAlert = false @State private var message: NoticeMessage.InboundMessage = .none @State private var cancel: AnyCancellable? - + + @State private var showMenu: Bool = false + var body: some View { VStack(alignment: .center, spacing: 10) { - - Image("logo") - - Text("PUNCHENT") - .font(.system(size: 46, weight: .bold)) - .foregroundColor(.white) - .cornerRadius(5.0) + VStack(alignment: .center, spacing: 10) { + Spacer() + .frame(height: 100) + + Image("logo") + .resizable() + .frame(width: 150, height: 150) + + Text("Connecting the Infinite") + .font(.system(size: 24, weight: .bold)) + .foregroundColor(.white) + .cornerRadius(5.0) + + Text("Welcome to PunchNet") + .font(.system(size: 14, weight: .regular)) + .foregroundColor(.white) + .cornerRadius(5.0) + } + .contentShape(Rectangle()) + .onTapGesture { + self.showMenu = false + } Spacer() .frame(width: 1, height: 10) - TextField("邀请码", text: $token) - .multilineTextAlignment(.center) - .frame(width: 245, height: 27) - .cornerRadius(5.0) + if showToken { + TextField("邀请码", text: $token) + .multilineTextAlignment(.leading) + .textFieldStyle(PlainTextFieldStyle()) + .frame(width: 200, height: 25) + .background(Color.white) + .foregroundColor(Color.black) + .cornerRadius(5.0) + } Spacer() .frame(width: 1, height: 10) - Button(action: { - Task { - switch self.vpnManager.vpnStatus { - case .connected: - try await vpnManager.disableVpn() - case .disconnected: - if self.token.isEmpty { - self.showAlert = true - return - } - try await vpnManager.enableVpn(options: [ - "version:": SystemConfig.version as NSObject, - "installed_channel": SystemConfig.installedChannel as NSObject, - "token": self.token as NSObject - ]) + Rectangle() + .overlay { + Text(vpnManager.title) + .font(.system(size: 14, weight: .regular)) + .foregroundColor(vpnManager.color) + } + .frame(width: 120, height: 35) + .foregroundColor(Color(red: 74 / 255, green: 207 / 255, blue: 154 / 255)) + .cornerRadius(5.0) + .onTapGesture { + Task { + try await self.clickSwitchButton() } } - }, label: { - Text(vpnManager.title) - .font(.system(size: 16, weight: .regular)) - .foregroundColor(vpnManager.color) - .cornerRadius(5.0) - }) - .frame(width: 138, height: 33) - .buttonStyle(PlainButtonStyle()) - .background(Color(red: 74 / 255, green: 207 / 255, blue: 154 / 255)) - .cornerRadius(5.0) + + Spacer() } - .frame(width: 380, height: 560) + .overlay(alignment: .top) { + + HStack(spacing: 200) { + HStack { + Button(action: { + NSApplication.shared.terminate(nil) + }) { + + Image("close") + .resizable() + .frame(width: 15, height: 15) + } + .buttonStyle(PlainButtonStyle()) + + Button(action: { + NSApplication.shared.keyWindow?.miniaturize(nil) + }) { + Image("line") + .resizable() + .frame(width: 15, height: 15) + } + .buttonStyle(PlainButtonStyle()) + } + + Button(action: { + showMenu.toggle() + }) { + Image("IosSettings") + .resizable() + .frame(width: 20, height: 20) + } + .buttonStyle(PlainButtonStyle()) + .overlay(alignment: .leading) { + showMenu ? + + GeometryReader { geometry in + + VStack(alignment: .leading, spacing: 8) { + Button(action: { + self.showMenu = false + }) { + Text("主页") + .font(.system(size: 14)) + .foregroundColor(.white) + } + .buttonStyle(PlainButtonStyle()) + + Button(action: { + self.showToken.toggle() + }) { + Text("邀请码") + .font(.system(size: 14)) + .foregroundColor(.white) + } + .buttonStyle(PlainButtonStyle()) + + Button(action: { + NSApplication.shared.terminate(nil) + }) { + Text("退出") + .font(.system(size: 14)) + .foregroundColor(.white) + } + .buttonStyle(PlainButtonStyle()) + } + .frame(width: 90, height: 80) + .background(Color(red: 50 / 255, green: 55 / 255, blue: 52 / 255)) + .offset(x: -55, y: 20) + } + + : nil + } + + } + .offset(x: 0, y: 10) + } + .frame(width: 300, height: 500) .background(Color(red: 36 / 255, green: 38 / 255, blue: 51 / 255)) .alert(isPresented: $showAlert) { Alert(title: Text("请输入正确的邀请码")) @@ -93,51 +180,31 @@ struct ContentView: View { } } } - - - /* - NavigationSplitView { - List { - ForEach(items) { item in - NavigationLink { - Text("Item at \(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard))") - } label: { - Text(item.timestamp, format: Date.FormatStyle(date: .numeric, time: .standard)) - } - } - .onDelete(perform: deleteItems) - } - .navigationSplitViewColumnWidth(min: 180, ideal: 200) - .toolbar { - ToolbarItem { - Button(action: addItem) { - Label("Add Item", systemImage: "plus") - } - } - } - } detail: { - Text("Select an item") - } - */ } - - private func addItem() { - withAnimation { - - } - } - - private func deleteItems(offsets: IndexSet) { - withAnimation { -// for index in offsets { -// modelContext.delete(items[index]) -// } + private func clickSwitchButton() async throws { + switch self.vpnManager.vpnStatus { + case .connected: + try await vpnManager.disableVpn() + case .disconnected: + /* + if self.token.isEmpty { + self.showAlert = true + return + } + */ + //print("use port: \(vpnManager.noticePort as NSObject)") + try await vpnManager.enableVpn(options: [ + "version:": SystemConfig.version as NSObject, + "installed_channel": SystemConfig.installedChannel as NSObject, + "token": self.token as NSObject + ]) } } + } #Preview { ContentView() - //.modelContainer(for: Item.self, inMemory: true) + //.modelContainer(for: Item.self, inMemory: true) }