Skip to content

Commit

Permalink
Add Settings page and SubscriptionScreen for XTLS config
Browse files Browse the repository at this point in the history
  • Loading branch information
svc-design committed Oct 18, 2024
1 parent 0ddf7f5 commit b01f842
Show file tree
Hide file tree
Showing 29 changed files with 437 additions and 243 deletions.
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

android {
namespace = "com.example.xstream"
namespace = "com.example.xstream_app"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion

Expand All @@ -21,7 +21,7 @@ android {

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.xstream"
applicationId = "com.example.xstream_app"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
Expand Down
2 changes: 1 addition & 1 deletion android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="xstream"
android:label="xstream_app"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.xstream_app

import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity()
29 changes: 29 additions & 0 deletions android/xstream_app_android.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="GEN_FOLDER_RELATIVE_PATH_APT" value="/gen" />
<option name="GEN_FOLDER_RELATIVE_PATH_AIDL" value="/gen" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/app/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/app/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/app/src/main/assets" />
<option name="LIBS_FOLDER_RELATIVE_PATH" value="/app/src/main/libs" />
<option name="PROGUARD_LOGS_FOLDER_RELATIVE_PATH" value="/app/src/main/proguard_logs" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/app/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/app/src/main/kotlin" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
</content>
<orderEntry type="jdk" jdkName="Android API 29 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Flutter for Android" level="project" />
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
</component>
</module>
12 changes: 6 additions & 6 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand All @@ -384,7 +384,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -401,7 +401,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
Expand All @@ -416,7 +416,7 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
Expand Down Expand Up @@ -547,7 +547,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -569,7 +569,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstream;
PRODUCT_BUNDLE_IDENTIFIER = com.example.xstreamApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand Down
4 changes: 2 additions & 2 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Xstream</string>
<string>Xstream App</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>xstream</string>
<string>xstream_app</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
Expand Down
62 changes: 54 additions & 8 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,68 @@
import 'package:flutter/material.dart';
import 'screens/home_screen.dart';
import 'screens/subscription_screen.dart';
import 'screens/settings_screen.dart';
import 'utils/app_theme.dart';

void main() {
runApp(const XStreamApp());
runApp(MyApp());
}

class XStreamApp extends StatelessWidget {
const XStreamApp({super.key});

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'XStream',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
home: MainPage(),
);
}
}

class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
int _currentIndex = 0;

final List<Widget> _pages = [
HomeScreen(),
SubscriptionScreen(),
SettingsScreen(),
];

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('XStream'),
),
body: _pages[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.link),
label: 'Subscriptions',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
),
home: const HomeScreen(),
);
}
}
155 changes: 126 additions & 29 deletions lib/screens/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,38 +1,135 @@
import 'package:flutter/material.dart';
import '../widgets/connection_form.dart';
import '../widgets/device_list.dart';
import '../widgets/service_status.dart';

class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// 检测屏幕宽度和平台
bool isLargeScreen = constraints.maxWidth > 600;
bool isDesktop = Theme.of(context).platform == TargetPlatform.macOS ||
Theme.of(context).platform == TargetPlatform.linux ||
Theme.of(context).platform == TargetPlatform.windows ||
Theme.of(context).platform == TargetPlatform.fuchsia;

return isLargeScreen && isDesktop
? Row(
children: [
// 左侧的状态信息和启动按钮
Expanded(
flex: 1,
child: Container(
color: Colors.grey[200],
padding: EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'服务状态',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Text('服务地址: http:// 或 Socks5://127.0.0.1:1080'),
SizedBox(height: 8),
Text('网络延迟: '),
SizedBox(height: 8),
Text('网络丢包: '),
Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'服务未运行',
style: TextStyle(color: Colors.red),
),
ElevatedButton(
onPressed: () {
// 启动服务的逻辑
},
child: Text('启动服务'),
),
],
),
],
),
),
),
// 右侧的配置列表
Expanded(
flex: 2,
child: ListView(
children: [
CustomListTile(title: 'VLESS', subtitle: 'tcp | none'),
CustomListTile(title: 'VMess', subtitle: 'tcp | none'),
CustomListTile(title: 'Shadowsocks', subtitle: 'tcp | none'),
CustomListTile(title: 'Trojan', subtitle: 'tcp | tls'),
CustomListTile(title: 'Socks', subtitle: 'tcp | none'),
],
),
),
],
)
: ListView(
children: [
// 仅显示配置项目,在每行的按钮上显示状态信息
CustomListTile(
title: 'VLESS',
subtitle: 'tcp | none',
status: '服务未运行', // 可根据具体状态动态显示
),
CustomListTile(
title: 'VMess',
subtitle: 'tcp | none',
status: '服务未运行',
),
CustomListTile(
title: 'Shadowsocks',
subtitle: 'tcp | none',
status: '服务未运行',
),
CustomListTile(
title: 'Trojan',
subtitle: 'tcp | tls',
status: '服务未运行',
),
CustomListTile(
title: 'Socks',
subtitle: 'tcp | none',
status: '服务未运行',
),
],
);
},
);
}
}

class CustomListTile extends StatelessWidget {
final String title;
final String subtitle;
final String? status;

const CustomListTile({
Key? key,
required this.title,
required this.subtitle,
this.status,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('XStream - 连接 XTLS 服务器'),
),
body: Row(
children: [
Expanded(
flex: 1,
child: Container(
padding: const EdgeInsets.all(16.0),
color: Colors.grey.shade200,
child: const ServiceStatus(),
),
),
Expanded(
flex: 2,
child: Column(
children: [
const ConnectionForm(), // 这里可以使用 const
Expanded(child: const DeviceList()),
],
),
),
],
),
return ListTile(
title: Text(title),
subtitle: Text(subtitle),
trailing: status != null
? Text(
status!,
style: TextStyle(color: status == '服务运行' ? Colors.green : Colors.red),
)
: null,
onTap: () {
// 点击事件逻辑,例如显示详细信息或启动服务
},
);
}
}
10 changes: 10 additions & 0 deletions lib/screens/settings_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'package:flutter/material.dart';

class SettingsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: Text('Settings Page'),
);
}
}
Loading

0 comments on commit b01f842

Please sign in to comment.