Skip to content

Commit

Permalink
Refactor subscription screen and lock button
Browse files Browse the repository at this point in the history
  • Loading branch information
svc-design committed Oct 22, 2024
1 parent d37a15b commit c3aee23
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 67 deletions.
60 changes: 31 additions & 29 deletions lib/screens/subscription_screen.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // 用于加载资产

class SubscriptionScreen extends StatefulWidget {
@override
Expand All @@ -12,39 +13,35 @@ class _SubscriptionScreenState extends State<SubscriptionScreen> {
final _uuidController = TextEditingController();
String _message = '';

Future<void> _generateConfig() async {
Future<String> _loadTemplate() async {
// 从 assets 目录加载模板文件
return await rootBundle.loadString('assets/xray-template.json');
}

Future<void> _generateConfig(String password) async {
final domain = _domainController.text;
final uuid = _uuidController.text;

// JSON 数据结构
final Map<String, dynamic> configData = {
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": domain,
"port": 443,
"users": [
{
"id": uuid,
"alterId": 0,
"security": "none",
}
]
}
]
}
}
],
// 其他配置项可以在此添加
};
// 加载模板
String template;
try {
template = await _loadTemplate();
} catch (e) {
setState(() {
_message = '加载模板失败: $e';
});
return;
}

// 替换模板中的占位符
String configContent = template
.replaceAll('<SERVER_DOMAIN>', domain)
.replaceAll('<UUID>', uuid);

// 将 JSON 数据写入文件
try {
final file = File('/opt/homebrew/etc/xray-vpn.json');
await file.writeAsString(json.encode(configData));
await file.writeAsString(configContent);
setState(() {
_message = '配置文件生成成功: ${file.path}';
});
Expand Down Expand Up @@ -83,8 +80,13 @@ class _SubscriptionScreenState extends State<SubscriptionScreen> {
),
SizedBox(height: 16),
ElevatedButton(
onPressed: _generateConfig,
child: Text('生成配置文件'),
onPressed: () {
// 显示提示信息或执行其他操作
setState(() {
_message = '请先输入域名和 UUID,然后使用右上角的解锁按钮生成配置文件。';
});
},
child: Text('提示信息'),
),
SizedBox(height: 16),
Text(
Expand All @@ -96,4 +98,4 @@ class _SubscriptionScreenState extends State<SubscriptionScreen> {
),
);
}
}
}
49 changes: 12 additions & 37 deletions lib/widgets/lock_button.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import 'package:flutter/material.dart';
import 'package:process_run/shell.dart';

class LockButton extends StatefulWidget {
final Function(String)? onUnlock; // Callback to pass the password to another component

const LockButton({Key? key, this.onUnlock}) : super(key: key);

@override
_LockButtonState createState() => _LockButtonState();
}
Expand All @@ -20,7 +23,7 @@ class _LockButtonState extends State<LockButton> {
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
labelText: 'Password',
labelText: '密码',
border: OutlineInputBorder(),
),
),
Expand All @@ -45,43 +48,15 @@ class _LockButtonState extends State<LockButton> {
}
}

Future<void> _attemptUnlock(String password) async {
var shell = Shell();
try {
// 示例命令,使用 sudo 提权
var results = await shell.run('''
echo $password | sudo -S echo "Checking permissions"
''');

// 取第一个 ProcessResult 来检查 exitCode
if (results.first.exitCode == 0) {
setState(() {
_isLocked = false;
});
} else {
_showError('密码错误或权限不足');
}
} catch (e) {
_showError('解锁失败: $e');
void _attemptUnlock(String password) {
// Call the provided callback function with the password
if (widget.onUnlock != null) {
widget.onUnlock!(password);
}
}

void _showError(String message) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('错误'),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('确定'),
),
],
);
},
);
setState(() {
_isLocked = false; // Assume unlock is successful for now
});
}

void _toggleLock() async {
Expand Down
23 changes: 23 additions & 0 deletions macos/Podfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
PODS:
- FlutterMacOS (1.0.0)
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS

DEPENDENCIES:
- FlutterMacOS (from `Flutter/ephemeral`)
- path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)

EXTERNAL SOURCES:
FlutterMacOS:
:path: Flutter/ephemeral
path_provider_foundation:
:path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin

SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46

PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367

COCOAPODS: 1.15.2
98 changes: 97 additions & 1 deletion macos/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
577F7BBC7187C647A603B36A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE50048310607D2C8CC996B5 /* Pods_Runner.framework */; };
89744575C6647F7A78FE1598 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 86FDAE893F867E2567CA8929 /* Pods_RunnerTests.framework */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -60,11 +62,12 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
1F85E2CCEDF9EFF90B94FFA5 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* xstream.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "xstream.app"; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10ED2044A3C60003C045 /* xstream.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = xstream.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
Expand All @@ -77,21 +80,30 @@
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
83313E40462B9654C42E5C1B /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
83BEB2A8F60CBCBD7FA349BA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
856D9C192D6B8C30E4E865E2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
86FDAE893F867E2567CA8929 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
B9576CA72E38290D2D6E285A /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
BE50048310607D2C8CC996B5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C59F29BA2EBAFF88A273AB9A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
331C80D2294CF70F00263BE5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
89744575C6647F7A78FE1598 /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
33CC10EA2044A3C60003C045 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
577F7BBC7187C647A603B36A /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -125,6 +137,7 @@
331C80D6294CF71000263BE5 /* RunnerTests */,
33CC10EE2044A3C60003C045 /* Products */,
D73912EC22F37F3D000D13A0 /* Frameworks */,
9047D6BB91B4C3719070EE8E /* Pods */,
);
sourceTree = "<group>";
};
Expand Down Expand Up @@ -172,9 +185,25 @@
path = Runner;
sourceTree = "<group>";
};
9047D6BB91B4C3719070EE8E /* Pods */ = {
isa = PBXGroup;
children = (
83BEB2A8F60CBCBD7FA349BA /* Pods-Runner.debug.xcconfig */,
1F85E2CCEDF9EFF90B94FFA5 /* Pods-Runner.release.xcconfig */,
C59F29BA2EBAFF88A273AB9A /* Pods-Runner.profile.xcconfig */,
83313E40462B9654C42E5C1B /* Pods-RunnerTests.debug.xcconfig */,
856D9C192D6B8C30E4E865E2 /* Pods-RunnerTests.release.xcconfig */,
B9576CA72E38290D2D6E285A /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
isa = PBXGroup;
children = (
BE50048310607D2C8CC996B5 /* Pods_Runner.framework */,
86FDAE893F867E2567CA8929 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
Expand All @@ -186,6 +215,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
2D1D6B8F0ED837A3FE5BB94B /* [CP] Check Pods Manifest.lock */,
331C80D1294CF70F00263BE5 /* Sources */,
331C80D2294CF70F00263BE5 /* Frameworks */,
331C80D3294CF70F00263BE5 /* Resources */,
Expand All @@ -204,11 +234,13 @@
isa = PBXNativeTarget;
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
F6535522E6F8EDE525FDC943 /* [CP] Check Pods Manifest.lock */,
33CC10E92044A3C60003C045 /* Sources */,
33CC10EA2044A3C60003C045 /* Frameworks */,
33CC10EB2044A3C60003C045 /* Resources */,
33CC110E2044A8840003C045 /* Bundle Framework */,
3399D490228B24CF009A79C7 /* ShellScript */,
E1D3DBF972B493BBFCC168E0 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
Expand Down Expand Up @@ -291,6 +323,28 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
2D1D6B8F0ED837A3FE5BB94B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3399D490228B24CF009A79C7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
Expand Down Expand Up @@ -329,6 +383,45 @@
shellPath = /bin/sh;
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
};
E1D3DBF972B493BBFCC168E0 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
F6535522E6F8EDE525FDC943 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -380,6 +473,7 @@
/* Begin XCBuildConfiguration section */
331C80DB294CF71000263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 83313E40462B9654C42E5C1B /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
Expand All @@ -394,6 +488,7 @@
};
331C80DC294CF71000263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 856D9C192D6B8C30E4E865E2 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
Expand All @@ -408,6 +503,7 @@
};
331C80DD294CF71000263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = B9576CA72E38290D2D6E285A /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
Expand Down
Loading

0 comments on commit c3aee23

Please sign in to comment.