feat: 添加应用品牌信息支持,重构主页 URL 生成逻辑
This commit is contained in:
@@ -4,6 +4,8 @@ enum Environment {
|
||||
|
||||
class AppConfig {
|
||||
static const Environment currentEnvironment = Environment.production;
|
||||
static const String appName = '本地打包';
|
||||
static const String appLogo = '';
|
||||
|
||||
static final Map<Environment, List<String>> _environmentHosts = {
|
||||
Environment.production: [
|
||||
@@ -15,11 +17,15 @@ class AppConfig {
|
||||
return _environmentHosts[currentEnvironment] ?? const [];
|
||||
}
|
||||
|
||||
static String get homeUrl {
|
||||
static String homeUrl({String? appName, String? appLogo}) {
|
||||
final host = environmentHosts.isNotEmpty
|
||||
? environmentHosts.first
|
||||
: 'h5-im.imharry.work';
|
||||
return _normalizeHomeUrl(host);
|
||||
return _withShellBranding(
|
||||
_normalizeHomeUrl(host),
|
||||
appName: appName,
|
||||
appLogo: appLogo,
|
||||
);
|
||||
}
|
||||
|
||||
static String _normalizeHomeUrl(String host) {
|
||||
@@ -29,4 +35,26 @@ class AppConfig {
|
||||
}
|
||||
return 'https://$value/';
|
||||
}
|
||||
|
||||
static String _withShellBranding(
|
||||
String url, {
|
||||
String? appName,
|
||||
String? appLogo,
|
||||
}) {
|
||||
final uri = Uri.parse(url);
|
||||
final queryParameters = Map<String, String>.from(uri.queryParameters)
|
||||
..['flutter_shell'] = '1';
|
||||
|
||||
final trimmedName = (appName ?? AppConfig.appName).trim();
|
||||
if (trimmedName.isNotEmpty) {
|
||||
queryParameters['shell_app_name'] = trimmedName;
|
||||
}
|
||||
|
||||
final trimmedLogo = (appLogo ?? AppConfig.appLogo).trim();
|
||||
if (trimmedLogo.isNotEmpty) {
|
||||
queryParameters['shell_app_logo'] = trimmedLogo;
|
||||
}
|
||||
|
||||
return uri.replace(queryParameters: queryParameters).toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@ import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
|
||||
|
||||
import 'config/app_config.dart';
|
||||
|
||||
final _homeUrl = AppConfig.homeUrl;
|
||||
const _shellBackground = Color(0xFFF8FBFF);
|
||||
const _shellAccent = Color(0xFF0089FF);
|
||||
const _shellSubText = Color(0xFF8E9AB0);
|
||||
const _resumeCoverDuration = Duration(milliseconds: 700);
|
||||
const _shellBrandingChannel =
|
||||
MethodChannel('io.openim.flutter.im_webview_app/shell_branding');
|
||||
const _stopWebMediaScript = r'''
|
||||
(() => {
|
||||
try {
|
||||
@@ -29,7 +30,7 @@ const _stopWebMediaScript = r'''
|
||||
})();
|
||||
''';
|
||||
|
||||
void main() {
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SystemChrome.setSystemUIOverlayStyle(
|
||||
const SystemUiOverlayStyle(
|
||||
@@ -39,29 +40,70 @@ void main() {
|
||||
systemNavigationBarIconBrightness: Brightness.dark,
|
||||
),
|
||||
);
|
||||
runApp(const ImWebViewApp());
|
||||
final shellBranding = await ShellBranding.load();
|
||||
runApp(ImWebViewApp(shellBranding: shellBranding));
|
||||
}
|
||||
|
||||
class ShellBranding {
|
||||
const ShellBranding({
|
||||
required this.appName,
|
||||
required this.appLogo,
|
||||
});
|
||||
|
||||
static const fallback = ShellBranding(
|
||||
appName: AppConfig.appName,
|
||||
appLogo: AppConfig.appLogo,
|
||||
);
|
||||
|
||||
final String appName;
|
||||
final String appLogo;
|
||||
|
||||
static Future<ShellBranding> load() async {
|
||||
try {
|
||||
final data = await _shellBrandingChannel
|
||||
.invokeMapMethod<String, String>('getShellBranding');
|
||||
final appName = _trim(data?['appName']);
|
||||
final appLogo = _trim(data?['appLogo']);
|
||||
|
||||
return ShellBranding(
|
||||
appName: appName.isNotEmpty ? appName : fallback.appName,
|
||||
appLogo: appLogo.isNotEmpty ? appLogo : fallback.appLogo,
|
||||
);
|
||||
} catch (_) {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
static String _trim(String? value) => value?.trim() ?? '';
|
||||
}
|
||||
|
||||
class ImWebViewApp extends StatelessWidget {
|
||||
const ImWebViewApp({super.key});
|
||||
const ImWebViewApp({
|
||||
super.key,
|
||||
this.shellBranding = ShellBranding.fallback,
|
||||
});
|
||||
|
||||
final ShellBranding shellBranding;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: '集中营',
|
||||
title: shellBranding.appName,
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF1F6FEB)),
|
||||
scaffoldBackgroundColor: _shellBackground,
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: const H5ShellPage(),
|
||||
home: H5ShellPage(shellBranding: shellBranding),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class H5ShellPage extends StatefulWidget {
|
||||
const H5ShellPage({super.key});
|
||||
const H5ShellPage({super.key, required this.shellBranding});
|
||||
|
||||
final ShellBranding shellBranding;
|
||||
|
||||
@override
|
||||
State<H5ShellPage> createState() => _H5ShellPageState();
|
||||
@@ -69,6 +111,7 @@ class H5ShellPage extends StatefulWidget {
|
||||
|
||||
class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
|
||||
late final WebViewController _controller;
|
||||
late final String _homeUrl;
|
||||
|
||||
int _progress = 0;
|
||||
String? _loadError;
|
||||
@@ -79,6 +122,10 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
_homeUrl = AppConfig.homeUrl(
|
||||
appName: widget.shellBranding.appName,
|
||||
appLogo: widget.shellBranding.appLogo,
|
||||
);
|
||||
_controller = _buildController()..loadRequest(Uri.parse(_homeUrl));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user