diff --git a/Dockerfile b/Dockerfile index 37a7669..a9482fb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,31 +1,9 @@ -FROM ubuntu:20.04 as flutter_build - -ENV DEBIAN_FRONTEND=noninteractive - -RUN apt-get update -RUN apt-get install -y curl git wget unzip libgconf-2-4 gdb libstdc++6 libglu1-mesa fonts-droid-fallback python3 -RUN apt-get clean - - -# download Flutter SDK from Flutter Github repo -RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter - -# Set flutter environment path -ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}" - -# Run flutter doctor -RUN flutter doctor - -# Enable flutter web -RUN flutter channel stable -RUN flutter upgrade -RUN flutter config --enable-web - -# Copy files to container and build -RUN mkdir /app/ -COPY . /app/ -WORKDIR /app/ -RUN flutter build web +FROM instrumentisto/flutter:3 AS flutter +WORKDIR /app +COPY ./ui/pubspec.yaml ./ui/pubspec.lock ./ +RUN flutter pub get +COPY ./ui/ ./ +RUN flutter build web # 打包依赖阶段使用golang作为基础镜像 @@ -37,14 +15,15 @@ ENV GO111MODULE=on \ WORKDIR /app -COPY --from=flutter_build go.mod . -COPY --from=flutter_build go.sum . +COPY go.mod . +COPY go.sum . RUN go mod download -COPY --from=flutter_build . . +COPY . . +COPY --from=flutter /app/build/web ./ui/build/web/ # 指定OS等,并go build -RUN GOOS=linux GOARCH=amd64 go build -o polaris ./cmd/ +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o polaris ./cmd/ FROM debian:12 diff --git a/db/db.go b/db/db.go index f34fde3..97aef7c 100644 --- a/db/db.go +++ b/db/db.go @@ -245,12 +245,19 @@ func (c *Client) AddStorage(s StorageInfo) error { SetImplementation(s.Implementation). SetPath(s.Path). SetUser(s.User). + SetDefault(s.Default). SetPassword(s.Password).Exec(context.TODO()) } + countAll := c.ent.Storage.Query().CountX(context.TODO()) + if countAll == 0 { + log.Infof("first storage, make it default: %s", s.Name) + s.Default = true + } _, err := c.ent.Storage.Create().SetName(s.Name). SetImplementation(s.Implementation). SetPath(s.Path). SetUser(s.User). + SetDefault(s.Default). SetPassword(s.Password).Save(context.TODO()) if err != nil { return err diff --git a/ui/lib/activity.dart b/ui/lib/activity.dart new file mode 100644 index 0000000..c98e02b --- /dev/null +++ b/ui/lib/activity.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class ActivityPage extends ConsumerWidget { + @override + Widget build(BuildContext context, WidgetRef ref) { + // TODO: implement build + throw UnimplementedError(); + } + +} \ No newline at end of file diff --git a/ui/lib/providers/settings.dart b/ui/lib/providers/settings.dart index b76e5cc..6e9f3a3 100644 --- a/ui/lib/providers/settings.dart +++ b/ui/lib/providers/settings.dart @@ -63,6 +63,9 @@ class IndexerSetting extends AsyncNotifier> { throw sp.message; } List indexers = List.empty(growable: true); + if (sp.data == null) { + return indexers; + } for (final item in sp.data as List) { indexers.add(Indexer.fromJson(item)); } @@ -128,6 +131,9 @@ class DownloadClientSetting extends AsyncNotifier> { throw sp.message; } List indexers = List.empty(growable: true); + if (sp.data == null) { + return indexers; + } for (final item in sp.data as List) { indexers.add(DownloadClient.fromJson(item)); } @@ -203,7 +209,6 @@ class DownloadClient { } class StorageSettingData extends AsyncNotifier> { - @override FutureOr> build() async { final dio = await APIs.getDio(); @@ -237,6 +242,7 @@ class StorageSettingData extends AsyncNotifier> { if (sp.code != 0) { throw sp.message; } + ref.invalidateSelf(); } } diff --git a/ui/lib/search.dart b/ui/lib/search.dart index 134a81b..c58b656 100644 --- a/ui/lib/search.dart +++ b/ui/lib/search.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:ui/providers/APIs.dart'; +import 'package:ui/providers/settings.dart'; import 'package:ui/providers/welcome_data.dart'; class SearchPage extends ConsumerStatefulWidget { @@ -89,12 +90,42 @@ class _SearchPageState extends ConsumerState { } Future _showSubmitDialog(BuildContext context, SearchResult item) { + TextEditingController resolutionController = + TextEditingController(text: "1080p"); + TextEditingController storageController = TextEditingController(); + var storage = ref.watch(storageSettingProvider); return showDialog( context: context, builder: (BuildContext context) { return AlertDialog( - title: const Text('添加剧集'), - content: Text("是否添加剧集: ${item.name}"), + title: Text('添加剧集: ${item.name}'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + DropdownMenu( + label: const Text("清晰度"), + controller: resolutionController, + dropdownMenuEntries: const [ + DropdownMenuEntry(value: "720p", label: "720p"), + DropdownMenuEntry(value: "1080p", label: "1080p"), + DropdownMenuEntry(value: "4k", label: "4k"), + ], + ), + storage.when( + data: (v) { + return DropdownMenu( + label: const Text("存储位置"), + controller: storageController, + dropdownMenuEntries: v + .map((s) => + DropdownMenuEntry(label: s.name!, value: s.id)) + .toList(), + ); + }, + error: (err, trace) => Text("$err"), + loading: () => const CircularProgressIndicator()), + ], + ), actions: [ TextButton( style: TextButton.styleFrom( diff --git a/ui/lib/tv_details.dart b/ui/lib/tv_details.dart index 6a00a94..c8f45a8 100644 --- a/ui/lib/tv_details.dart +++ b/ui/lib/tv_details.dart @@ -72,8 +72,7 @@ class _TvDetailsPageState extends ConsumerState { }); if (!Utils.showError(context, snapshot)) { var name = await f; - Utils.showSnakeBar( - context, "开始下载: $name"); + Utils.showSnakeBar(context, "开始下载: $name"); } }, icon: const Icon(Icons.search)) @@ -140,7 +139,11 @@ class _TvDetailsPageState extends ConsumerState { error: (err, trace) { return Text("$err"); }, - loading: () => const CircularProgressIndicator()); + loading: () => const Center( + child: SizedBox( + width: 30, + height: 30, + child: CircularProgressIndicator()))); }); } } diff --git a/ui/lib/weclome.dart b/ui/lib/weclome.dart index cbe39bb..5e9ef5f 100644 --- a/ui/lib/weclome.dart +++ b/ui/lib/weclome.dart @@ -16,7 +16,7 @@ class WelcomePage extends ConsumerWidget { return switch (data) { AsyncData(:final value) => GridView.builder( - padding: const EdgeInsets.all(30), + padding: const EdgeInsets.all(30), itemCount: value.length, gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 6), @@ -48,7 +48,9 @@ class WelcomePage extends ConsumerWidget { ), )); }), - _ => const CircularProgressIndicator(), + _ => const Center( + child: SizedBox( + width: 30, height: 30, child: CircularProgressIndicator())), }; } }