mirror of
https://github.com/simon-ding/polaris.git
synced 2026-04-21 19:27:30 +08:00
feat: add name suggesting
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:ui/activity.dart';
|
||||
import 'package:ui/search.dart';
|
||||
import 'package:ui/system_settings.dart';
|
||||
import 'package:ui/welcome_page.dart';
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ class APIs {
|
||||
static final watchlistMovieUrl = "$_baseUrl/api/v1/media/movie/watchlist";
|
||||
static final availableMoviesUrl = "$_baseUrl/api/v1/media/movie/resources/";
|
||||
static final seriesDetailUrl = "$_baseUrl/api/v1/media/record/";
|
||||
static final suggestedTvName = "$_baseUrl/api/v1/media/suggest/";
|
||||
static final searchAndDownloadUrl = "$_baseUrl/api/v1/indexer/download";
|
||||
static final allIndexersUrl = "$_baseUrl/api/v1/indexer/";
|
||||
static final addIndexerUrl = "$_baseUrl/api/v1/indexer/add";
|
||||
|
||||
@@ -17,6 +17,18 @@ final tvWatchlistDataProvider = FutureProvider.autoDispose((ref) async {
|
||||
return favList;
|
||||
});
|
||||
|
||||
final suggestNameDataProvider = FutureProvider.autoDispose.family(
|
||||
(ref, int arg) async {
|
||||
final dio = await APIs.getDio();
|
||||
var resp = await dio.get(APIs.suggestedTvName + arg.toString());
|
||||
var sp = ServerResponse.fromJson(resp.data);
|
||||
if (sp.code != 0) {
|
||||
throw sp.message;
|
||||
}
|
||||
return sp.data["name"] as String;
|
||||
},
|
||||
);
|
||||
|
||||
final movieWatchlistDataProvider = FutureProvider.autoDispose((ref) async {
|
||||
final dio = await APIs.getDio();
|
||||
var resp = await dio.get(APIs.watchlistMovieUrl);
|
||||
@@ -75,14 +87,15 @@ class SearchPageData
|
||||
state = newState;
|
||||
}
|
||||
|
||||
Future<void> submit2Watchlist(
|
||||
int tmdbId, int storageId, String resolution, String mediaType) async {
|
||||
Future<void> submit2Watchlist(int tmdbId, int storageId, String resolution,
|
||||
String mediaType, String folder) async {
|
||||
final dio = await APIs.getDio();
|
||||
if (mediaType == "tv") {
|
||||
var resp = await dio.post(APIs.watchlistTvUrl, data: {
|
||||
"tmdb_id": tmdbId,
|
||||
"storage_id": storageId,
|
||||
"resolution": resolution
|
||||
"resolution": resolution,
|
||||
"folder": folder
|
||||
});
|
||||
var sp = ServerResponse.fromJson(resp.data);
|
||||
if (sp.code != 0) {
|
||||
@@ -93,7 +106,8 @@ class SearchPageData
|
||||
var resp = await dio.post(APIs.watchlistMovieUrl, data: {
|
||||
"tmdb_id": tmdbId,
|
||||
"storage_id": storageId,
|
||||
"resolution": resolution
|
||||
"resolution": resolution,
|
||||
"folder": folder
|
||||
});
|
||||
var sp = ServerResponse.fromJson(resp.data);
|
||||
if (sp.code != 0) {
|
||||
@@ -116,9 +130,11 @@ class SearchResponse {
|
||||
page: json["page"],
|
||||
totalPage: json["total_page"],
|
||||
totalResults: json["total_results"],
|
||||
results: json["results"] == null ? []: json["results"]
|
||||
.map((v) => SearchResult.fromJson(v))
|
||||
.toList());
|
||||
results: json["results"] == null
|
||||
? []
|
||||
: (json["results"] as List)
|
||||
.map((v) => SearchResult.fromJson(v))
|
||||
.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,8 +98,8 @@ class _SearchPageState extends ConsumerState<SearchPage> {
|
||||
var f = NotificationListener(
|
||||
onNotification: (ScrollNotification scrollInfo) {
|
||||
if (scrollInfo is ScrollEndNotification &&
|
||||
scrollInfo.metrics.axisDirection == AxisDirection.down &&
|
||||
scrollInfo.metrics.pixels >= scrollInfo.metrics.maxScrollExtent) {
|
||||
scrollInfo.metrics.axisDirection == AxisDirection.down &&
|
||||
scrollInfo.metrics.pixels >= scrollInfo.metrics.maxScrollExtent) {
|
||||
ref.read(searchPageDataProvider(q).notifier).queryNextPage();
|
||||
}
|
||||
return true;
|
||||
@@ -136,45 +136,84 @@ class _SearchPageState extends ConsumerState<SearchPage> {
|
||||
String resSelected = "1080p";
|
||||
int storageSelected = 0;
|
||||
var storage = ref.watch(storageSettingProvider);
|
||||
var name = ref.watch(suggestNameDataProvider(item.id!));
|
||||
|
||||
var pathController = TextEditingController();
|
||||
return AlertDialog(
|
||||
title: Text('添加剧集: ${item.name}'),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DropdownMenu(
|
||||
label: const Text("清晰度"),
|
||||
initialSelection: resSelected,
|
||||
dropdownMenuEntries: const [
|
||||
DropdownMenuEntry(value: "720p", label: "720p"),
|
||||
DropdownMenuEntry(value: "1080p", label: "1080p"),
|
||||
DropdownMenuEntry(value: "4k", label: "4k"),
|
||||
],
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
resSelected = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
storage.when(
|
||||
data: (v) {
|
||||
return DropdownMenu(
|
||||
label: const Text("存储位置"),
|
||||
initialSelection: storageSelected,
|
||||
dropdownMenuEntries: v
|
||||
.map((s) => DropdownMenuEntry(
|
||||
label: s.name!, value: s.id))
|
||||
.toList(),
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
storageSelected = value!;
|
||||
});
|
||||
},
|
||||
);
|
||||
content: SizedBox(
|
||||
width: 500,
|
||||
height: 200,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DropdownMenu(
|
||||
label: const Text("清晰度"),
|
||||
initialSelection: resSelected,
|
||||
dropdownMenuEntries: const [
|
||||
DropdownMenuEntry(value: "720p", label: "720p"),
|
||||
DropdownMenuEntry(value: "1080p", label: "1080p"),
|
||||
DropdownMenuEntry(value: "4k", label: "4k"),
|
||||
],
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
resSelected = value!;
|
||||
});
|
||||
},
|
||||
error: (err, trace) => Text("$err"),
|
||||
loading: () => const MyProgressIndicator()),
|
||||
],
|
||||
),
|
||||
|
||||
storage.when(
|
||||
data: (v) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
DropdownMenu(
|
||||
label: const Text("存储位置"),
|
||||
initialSelection: storageSelected,
|
||||
dropdownMenuEntries: v
|
||||
.map((s) => DropdownMenuEntry(
|
||||
label: s.name!, value: s.id))
|
||||
.toList(),
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
storageSelected = value!;
|
||||
});
|
||||
},
|
||||
),
|
||||
|
||||
name.when(
|
||||
data: (s) {
|
||||
|
||||
final path = item.mediaType == "tv"
|
||||
? v[storageSelected]
|
||||
.settings!["tv_path"]
|
||||
: v[storageSelected]
|
||||
.settings!["movie_path"];
|
||||
pathController.text = s;
|
||||
return SizedBox(
|
||||
//width: 300,
|
||||
child: TextField (
|
||||
|
||||
controller: pathController,
|
||||
decoration: InputDecoration(
|
||||
labelText: "存储路径",
|
||||
prefix: Text(path)
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => Text("$error"),
|
||||
loading: () => const MyProgressIndicator(
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
error: (err, trace) => Text("$err"),
|
||||
loading: () => const MyProgressIndicator()),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
@@ -195,8 +234,12 @@ class _SearchPageState extends ConsumerState<SearchPage> {
|
||||
ref
|
||||
.read(searchPageDataProvider(widget.query ?? "")
|
||||
.notifier)
|
||||
.submit2Watchlist(item.id!, storageSelected,
|
||||
resSelected, item.mediaType!);
|
||||
.submit2Watchlist(
|
||||
item.id!,
|
||||
storageSelected,
|
||||
resSelected,
|
||||
item.mediaType!,
|
||||
pathController.text);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user