mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-09 03:27:39 +08:00
welcome page update
This commit is contained in:
@@ -2,6 +2,7 @@ class APIs {
|
||||
static const _baseUrl = "http://127.0.0.1:8080";
|
||||
static const searchUrl = "$_baseUrl/api/v1/tv/search";
|
||||
static const settingsUrl = "$_baseUrl/api/v1/setting/do";
|
||||
static const watchlistUrl = "$_baseUrl/api/v1/tv/watchlist";
|
||||
|
||||
static const tmdbImgBaseUrl = "https://image.tmdb.org/t/p/w500/";
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ class _SearchPageState extends State<SearchPage> {
|
||||
Widget build(BuildContext context) {
|
||||
var cards = List<Widget>.empty(growable: true);
|
||||
for (final item in list) {
|
||||
var m = item as Map<String, dynamic>;
|
||||
var m = SearchResult.fromJson(item);
|
||||
cards.add(Card(
|
||||
margin: const EdgeInsets.all(4),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
@@ -50,7 +50,7 @@ class _SearchPageState extends State<SearchPage> {
|
||||
//splashColor: Colors.blue.withAlpha(30),
|
||||
onTap: () {
|
||||
//showDialog(context: context, builder: builder)
|
||||
debugPrint('Card tapped.');
|
||||
_showSubmitDialog(context, m);
|
||||
},
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
@@ -59,7 +59,7 @@ class _SearchPageState extends State<SearchPage> {
|
||||
width: 150,
|
||||
height: 200,
|
||||
child: Image.network(
|
||||
APIs.tmdbImgBaseUrl + m["poster_path"],
|
||||
APIs.tmdbImgBaseUrl + m.posterPath!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
@@ -69,12 +69,12 @@ class _SearchPageState extends State<SearchPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
m["name"],
|
||||
m.name!,
|
||||
style: const TextStyle(
|
||||
fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const Text(""),
|
||||
Text(m["overview"])
|
||||
Text(m.overview!)
|
||||
],
|
||||
),
|
||||
)
|
||||
@@ -83,25 +83,64 @@ class _SearchPageState extends State<SearchPage> {
|
||||
)));
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
autofocus: true,
|
||||
onSubmitted: (value) => _queryResults(context,value),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "搜索",
|
||||
hintText: "搜索剧集名称",
|
||||
prefixIcon: Icon(Icons.search)),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: cards,
|
||||
))
|
||||
],
|
||||
),
|
||||
return Column(
|
||||
children: [
|
||||
TextField(
|
||||
autofocus: true,
|
||||
onSubmitted: (value) => _queryResults(context, value),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "搜索",
|
||||
hintText: "搜索剧集名称",
|
||||
prefixIcon: Icon(Icons.search)),
|
||||
),
|
||||
Expanded(
|
||||
child: ListView(
|
||||
children: cards,
|
||||
))
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showSubmitDialog(BuildContext context, SearchResult item) {
|
||||
return showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text('添加剧集'),
|
||||
content: Text("是否添加剧集: ${item.name}"),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
child: const Text('取消'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
textStyle: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
child: const Text('确定'),
|
||||
onPressed: () {
|
||||
_submit2Watchlist(context, item.id!);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void _submit2Watchlist(BuildContext context, int id) async {
|
||||
var resp = await Dio()
|
||||
.post(APIs.watchlistUrl, data: {"id": id, "folder": "/downloads"});
|
||||
var sp = ServerResponse.fromJson(resp.data);
|
||||
if (sp.code != 0 && context.mounted) {
|
||||
Utils.showAlertDialog(context, sp.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SearchBarApp extends StatefulWidget {
|
||||
@@ -142,3 +181,50 @@ class _SearchBarAppState extends State<SearchBarApp> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class SearchResult {
|
||||
String? originalName;
|
||||
int? id;
|
||||
String? name;
|
||||
int? voteCount;
|
||||
double? voteAverage;
|
||||
String? posterPath;
|
||||
String? firstAirDate;
|
||||
double? popularity;
|
||||
List<int>? genreIds;
|
||||
String? originalLanguage;
|
||||
String? backdropPath;
|
||||
String? overview;
|
||||
List<String>? originCountry;
|
||||
|
||||
SearchResult(
|
||||
{this.originalName,
|
||||
this.id,
|
||||
this.name,
|
||||
this.voteCount,
|
||||
this.voteAverage,
|
||||
this.posterPath,
|
||||
this.firstAirDate,
|
||||
this.popularity,
|
||||
this.genreIds,
|
||||
this.originalLanguage,
|
||||
this.backdropPath,
|
||||
this.overview,
|
||||
this.originCountry});
|
||||
|
||||
SearchResult.fromJson(Map<String, dynamic> json) {
|
||||
originalName = json['original_name'];
|
||||
id = json['id'];
|
||||
name = json['name'];
|
||||
voteCount = json['vote_count'];
|
||||
voteAverage = json['vote_average'];
|
||||
posterPath = json['poster_path'];
|
||||
firstAirDate = json['first_air_date'];
|
||||
popularity = json['popularity'];
|
||||
genreIds = json['genre_ids'].cast<int>();
|
||||
originalLanguage = json['original_language'];
|
||||
backdropPath = json['backdrop_path'];
|
||||
overview = json['overview'];
|
||||
originCountry = json['origin_country'].cast<String>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import 'package:ui/utils.dart';
|
||||
|
||||
class SystemSettingsPage extends StatefulWidget {
|
||||
static const route = "/systemsettings";
|
||||
|
||||
const SystemSettingsPage({super.key});
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _SystemSettingsPageState();
|
||||
@@ -19,8 +21,7 @@ class _SystemSettingsPageState extends State<SystemSettingsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_handleRefresh();
|
||||
return Expanded(
|
||||
child: Container(
|
||||
return Container(
|
||||
padding: const EdgeInsets.fromLTRB(40, 10, 40, 0),
|
||||
child: RefreshIndicator(
|
||||
onRefresh: _handleRefresh,
|
||||
@@ -63,7 +64,7 @@ class _SystemSettingsPageState extends State<SystemSettingsPage> {
|
||||
],
|
||||
),
|
||||
)),
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _handleRefresh() async {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:ui/APIs.dart';
|
||||
import 'package:ui/server_response.dart';
|
||||
|
||||
class WelcomePage extends StatefulWidget {
|
||||
const WelcomePage({super.key});
|
||||
@@ -16,57 +18,85 @@ class _WeclomePageState extends State<WelcomePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var cards = List<Widget>.empty(growable: true);
|
||||
for (final item in favList) {
|
||||
var m = item as Map<String, dynamic>;
|
||||
cards.add(Card(
|
||||
margin: const EdgeInsets.all(4),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
//splashColor: Colors.blue.withAlpha(30),
|
||||
onTap: () {
|
||||
//showDialog(context: context, builder: builder)
|
||||
debugPrint('Card tapped.');
|
||||
},
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
width: 150,
|
||||
height: 200,
|
||||
child: Image.network(
|
||||
APIs.tmdbImgBaseUrl + m["poster_path"],
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
m["name"],
|
||||
style: const TextStyle(
|
||||
fontSize: 14, fontWeight: FontWeight.bold),
|
||||
_onRefresh();
|
||||
return GridView.builder(
|
||||
itemCount: favList.length,
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 4),
|
||||
itemBuilder: (context, i) {
|
||||
var item = TvSeries.fromJson(favList[i]);
|
||||
return Container(
|
||||
child: Card(
|
||||
margin: const EdgeInsets.all(4),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
//splashColor: Colors.blue.withAlpha(30),
|
||||
onTap: () {
|
||||
//showDialog(context: context, builder: builder)
|
||||
},
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: SizedBox(
|
||||
width: 300,
|
||||
height: 600,
|
||||
child: Image.network(
|
||||
APIs.tmdbImgBaseUrl + item.posterPath!,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
item.title!,
|
||||
style: const TextStyle(
|
||||
fontSize: 14, fontWeight: FontWeight.bold),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
const Text(""),
|
||||
Text(m["overview"])
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)));
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: _onRefresh,
|
||||
child: Expanded(
|
||||
child: ListView(
|
||||
children: cards,
|
||||
))));
|
||||
)),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _onRefresh() async {}
|
||||
Future<void> _onRefresh() async {
|
||||
if (favList.isNotEmpty) {
|
||||
return;
|
||||
}
|
||||
var resp = await Dio().get(APIs.watchlistUrl);
|
||||
var sp = ServerResponse.fromJson(resp.data);
|
||||
setState(() {
|
||||
favList = sp.data as List;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class TvSeries {
|
||||
int? id;
|
||||
int? tmdbId;
|
||||
String? title;
|
||||
String? originalName;
|
||||
String? overview;
|
||||
String? path;
|
||||
String? posterPath;
|
||||
|
||||
TvSeries(
|
||||
{this.id,
|
||||
this.tmdbId,
|
||||
this.title,
|
||||
this.originalName,
|
||||
this.overview,
|
||||
this.path,
|
||||
this.posterPath});
|
||||
|
||||
TvSeries.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
tmdbId = json['tmdb_id'];
|
||||
title = json['title'];
|
||||
originalName = json['original_name'];
|
||||
overview = json['overview'];
|
||||
path = json['path'];
|
||||
posterPath = json["poster_path"];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user