From bfcbf5402db5707dbda6b8bcba31e1c53525f204 Mon Sep 17 00:00:00 2001 From: PartyDonut <42371342+PartyDonut@users.noreply.github.com> Date: Thu, 17 Oct 2024 19:06:13 +0200 Subject: [PATCH] Web - Add docker image and baseUrl config support (#32) --- .dockerignore | 25 +++++++++++ .github/workflows/build.yml | 8 ++++ .metadata | 12 ++--- Dockerfile | 11 +++++ config/config.json | 3 ++ lib/android_tv/main.dart | 61 -------------------------- lib/main.dart | 19 ++++++-- lib/screens/login/login_edit_user.dart | 8 ++-- lib/screens/login/login_screen.dart | 58 +++++++++++++----------- lib/util/fladder_config.dart | 17 +++++++ pubspec.yaml | 1 + web/index.html | 59 ++++++++----------------- 12 files changed, 144 insertions(+), 138 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 config/config.json delete mode 100644 lib/android_tv/main.dart create mode 100644 lib/util/fladder_config.dart diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3dbbcf3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/bin +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49b7068..cb3199a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -278,3 +278,11 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} # Automatically provided by GitHub Actions publish_dir: ./build/web + + - name: Deploy to ghcr.io + uses: mr-smithers-excellent/docker-build-push@v6 + with: + image: fladder + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} diff --git a/.metadata b/.metadata index fce676f..8dda3be 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "2f708eb8396e362e280fac22cf171c2cb467343c" + revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" channel: "stable" project_type: app @@ -13,11 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c - base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c - - platform: android - create_revision: 2f708eb8396e362e280fac22cf171c2cb467343c - base_revision: 2f708eb8396e362e280fac22cf171c2cb467343c + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + - platform: web + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 # User provided section diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2f5619c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM nginx:alpine + +EXPOSE 80 + +ENV BASE_URL="" + +COPY build/web /usr/share/nginx/html + +RUN echo '{"baseUrl": "${BASE_URL}"}' > /usr/share/nginx/html/assets/config/config.json + +CMD /bin/sh -c 'sed -i "s|\${BASE_URL}|${BASE_URL}|g" /usr/share/nginx/html/assets/config/config.json && nginx -g "daemon off;"' diff --git a/config/config.json b/config/config.json new file mode 100644 index 0000000..78ec775 --- /dev/null +++ b/config/config.json @@ -0,0 +1,3 @@ +{ + "baseUrl": null +} \ No newline at end of file diff --git a/lib/android_tv/main.dart b/lib/android_tv/main.dart deleted file mode 100644 index 2babcb6..0000000 --- a/lib/android_tv/main.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; - -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:logging/logging.dart'; -import 'package:media_kit/media_kit.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -import 'package:fladder/providers/shared_provider.dart'; -import 'package:fladder/util/application_info.dart'; -import 'package:fladder/util/string_extensions.dart'; - -void main() async { - _setupLogging(); - WidgetsFlutterBinding.ensureInitialized(); - MediaKit.ensureInitialized(); - - final sharedPreferences = await SharedPreferences.getInstance(); - - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - - runApp( - ProviderScope( - overrides: [ - sharedPreferencesProvider.overrideWith((ref) => sharedPreferences), - applicationInfoProvider.overrideWith( - (ref) => ApplicationInfo( - name: packageInfo.appName, - buildNumber: packageInfo.buildNumber, - version: packageInfo.version, - os: defaultTargetPlatform.name.capitalize(), - ), - ), - ], - child: const Main(), - ), - ); -} - -void _setupLogging() { - Logger.root.level = Level.ALL; - Logger.root.onRecord.listen((rec) { - if (kDebugMode) { - print('${rec.level.name}: ${rec.time}: ${rec.message}'); - } - }); -} - -class Main extends ConsumerWidget { - const Main({super.key}); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return const MaterialApp( - home: Scaffold( - body: Center(child: Text("AndroidTV")), - ), - ); - } -} diff --git a/lib/main.dart b/lib/main.dart index f07fdc9..013aaa5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'dart:ui'; @@ -32,6 +34,7 @@ import 'package:fladder/screens/login/lock_screen.dart'; import 'package:fladder/theme.dart'; import 'package:fladder/util/adaptive_layout.dart'; import 'package:fladder/util/application_info.dart'; +import 'package:fladder/util/fladder_config.dart'; import 'package:fladder/util/string_extensions.dart'; import 'package:fladder/util/themes_data.dart'; @@ -57,14 +60,24 @@ class CustomCacheManager { ); } +Future> loadConfig() async { + final configString = await rootBundle.loadString('config/config.json'); + return jsonDecode(configString); +} + void main() async { - if (kIsWeb) { - html.document.onContextMenu.listen((event) => event.preventDefault()); - } _setupLogging(); WidgetsFlutterBinding.ensureInitialized(); MediaKit.ensureInitialized(); + if (kIsWeb) { + html.document.onContextMenu.listen((event) => event.preventDefault()); + final result = await loadConfig(); + log(result.toString()); + FladderConfig.fromJson(result); + log(FladderConfig.baseUrl.toString()); + } + final sharedPreferences = await SharedPreferences.getInstance(); PackageInfo packageInfo = await PackageInfo.fromPlatform(); diff --git a/lib/screens/login/login_edit_user.dart b/lib/screens/login/login_edit_user.dart index 146f679..c5ea1bb 100644 --- a/lib/screens/login/login_edit_user.dart +++ b/lib/screens/login/login_edit_user.dart @@ -1,11 +1,13 @@ +import 'package:flutter/material.dart'; + import 'package:ficonsax/ficonsax.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:intl/intl.dart'; + import 'package:fladder/models/account_model.dart'; import 'package:fladder/providers/auth_provider.dart'; import 'package:fladder/providers/shared_provider.dart'; import 'package:fladder/util/list_padding.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:intl/intl.dart'; class LoginEditUser extends ConsumerWidget { final AccountModel user; diff --git a/lib/screens/login/login_screen.dart b/lib/screens/login/login_screen.dart index 4b18db2..781f9ed 100644 --- a/lib/screens/login/login_screen.dart +++ b/lib/screens/login/login_screen.dart @@ -23,6 +23,7 @@ import 'package:fladder/screens/shared/outlined_text_field.dart'; import 'package:fladder/screens/shared/passcode_input.dart'; import 'package:fladder/util/adaptive_layout.dart'; import 'package:fladder/util/auth_service.dart'; +import 'package:fladder/util/fladder_config.dart'; import 'package:fladder/util/list_padding.dart'; import 'package:fladder/util/localization_helper.dart'; import 'package:fladder/util/string_extensions.dart'; @@ -43,7 +44,7 @@ class _LoginPageState extends ConsumerState { bool startCheckingForErrors = false; bool addingNewUser = false; bool editingUsers = false; - late final TextEditingController serverTextController = TextEditingController(text: ""); + late final TextEditingController serverTextController = TextEditingController(text: ''); final usernameController = TextEditingController(); final passwordController = TextEditingController(); @@ -64,6 +65,11 @@ class _LoginPageState extends ConsumerState { final currentAccounts = ref.read(authProvider.notifier).getSavedAccounts(); addingNewUser = currentAccounts.isEmpty; ref.read(lockScreenActiveProvider.notifier).update((state) => true); + if (FladderConfig.baseUrl != null) { + serverTextController.text = FladderConfig.baseUrl!; + _parseUrl(FladderConfig.baseUrl!); + retrieveListOfUsers(); + } }); } @@ -258,7 +264,7 @@ class _LoginPageState extends ConsumerState { return Column( children: [ Row( - mainAxisAlignment: MainAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ if (accounts.isNotEmpty) @@ -282,33 +288,35 @@ class _LoginPageState extends ConsumerState { ), ), ), - Flexible( - child: OutlinedTextField( - controller: serverTextController, - onChanged: _parseUrl, - onSubmitted: (value) => retrieveListOfUsers(), - autoFillHints: const [AutofillHints.url], - keyboardType: TextInputType.url, - textInputAction: TextInputAction.go, - label: context.localized.server, - errorText: (invalidUrl == null || serverTextController.text.isEmpty || !startCheckingForErrors) - ? null - : invalidUrl, + if (FladderConfig.baseUrl == null) ...[ + Flexible( + child: OutlinedTextField( + controller: serverTextController, + onChanged: _parseUrl, + onSubmitted: (value) => retrieveListOfUsers(), + autoFillHints: const [AutofillHints.url], + keyboardType: TextInputType.url, + textInputAction: TextInputAction.go, + label: context.localized.server, + errorText: (invalidUrl == null || serverTextController.text.isEmpty || !startCheckingForErrors) + ? null + : invalidUrl, + ), ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Tooltip( - message: context.localized.retrievePublicListOfUsers, - waitDuration: const Duration(seconds: 1), - child: IconButton.filled( - onPressed: () => retrieveListOfUsers(), - icon: const Icon( - IconsaxOutline.refresh, + Padding( + padding: const EdgeInsets.all(8.0), + child: Tooltip( + message: context.localized.retrievePublicListOfUsers, + waitDuration: const Duration(seconds: 1), + child: IconButton.filled( + onPressed: () => retrieveListOfUsers(), + icon: const Icon( + IconsaxOutline.refresh, + ), ), ), ), - ), + ], ], ), AnimatedFadeSize( diff --git a/lib/util/fladder_config.dart b/lib/util/fladder_config.dart new file mode 100644 index 0000000..e54040f --- /dev/null +++ b/lib/util/fladder_config.dart @@ -0,0 +1,17 @@ +class FladderConfig { + static FladderConfig _instance = FladderConfig._(); + FladderConfig._(); + + static String? get baseUrl => _instance._baseUrl; + static set baseUrl(String? value) => _instance._baseUrl = value; + String? _baseUrl; + + static void fromJson(Map json) => _instance = FladderConfig._fromJson(json); + + factory FladderConfig._fromJson(Map json) { + final config = FladderConfig._(); + final newUrl = json['baseUrl'] as String?; + config._baseUrl = newUrl?.isEmpty == true ? null : newUrl; + return config; + } +} diff --git a/pubspec.yaml b/pubspec.yaml index 428534f..effd7df 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -159,6 +159,7 @@ flutter: assets: - icons/ - assets/fonts/ + - config/ fonts: - family: mp-font diff --git a/web/index.html b/web/index.html index fc6f3db..b48184b 100644 --- a/web/index.html +++ b/web/index.html @@ -1,7 +1,7 @@ - - - + - - - + + + - - - - - + + + + + - - + + - fladder - - - - - - - - - + Fladder + + + + +