refactor: use short names for genres
parent
a0e4edb508
commit
497c2e6d2e
|
@ -25,6 +25,7 @@ class WikidataProperties {
|
||||||
static const String reviewScore = "P444";
|
static const String reviewScore = "P444";
|
||||||
static const String fskFilmRating = "P1981";
|
static const String fskFilmRating = "P1981";
|
||||||
static const String placeOfPublication = "P291";
|
static const String placeOfPublication = "P291";
|
||||||
|
static const String shortName = "P1813";
|
||||||
}
|
}
|
||||||
|
|
||||||
class WikidataEntities {
|
class WikidataEntities {
|
||||||
|
@ -236,16 +237,24 @@ Future<Map<String, String>> _getLabelsForEntities(
|
||||||
final start = i * batchSize;
|
final start = i * batchSize;
|
||||||
final end = min((i + 1) * batchSize, entityIds.length);
|
final end = min((i + 1) * batchSize, entityIds.length);
|
||||||
Response response = await _wikidataApi.get(
|
Response response = await _wikidataApi.get(
|
||||||
"&action=wbgetentities&format=json&props=labels&ids=${entityIds.sublist(start, end).join("|")}");
|
"&action=wbgetentities&format=json&props=labels|claims&ids=${entityIds.sublist(start, end).join("|")}");
|
||||||
Map<String, dynamic> result = jsonDecode(response.body);
|
Map<String, dynamic> result = jsonDecode(response.body);
|
||||||
Map<String, dynamic> batchEntities = result["entities"];
|
Map<String, dynamic> batchEntities = result["entities"];
|
||||||
for (String entityId in batchEntities.keys) {
|
for (String entityId in batchEntities.keys) {
|
||||||
Map<String, dynamic> labels = batchEntities[entityId]["labels"];
|
String? shortName = selectInJson(batchEntities[entityId],
|
||||||
String label = labels.containsKey("en")
|
"claims.${WikidataProperties.shortName}.*.mainsnak.datavalue.value")
|
||||||
? labels["en"]["value"]
|
.where((value) => value["language"] == "en")
|
||||||
: labels[labels.keys.first]["value"];
|
.map((value) => (value["text"] as String))
|
||||||
labels[entityId] = label;
|
.firstOrNull;
|
||||||
_labelCache[entityId] = label;
|
Map<String, dynamic> responseLabels = batchEntities[entityId]["labels"];
|
||||||
|
if (shortName != null) {
|
||||||
|
_labelCache[entityId] = labels[entityId] = shortName;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String label = responseLabels.containsKey("en")
|
||||||
|
? responseLabels["en"]["value"]
|
||||||
|
: responseLabels[responseLabels.keys.first]["value"];
|
||||||
|
_labelCache[entityId] = labels[entityId] = label;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return labels;
|
return labels;
|
||||||
|
|
|
@ -3,16 +3,21 @@ import 'dart:async';
|
||||||
class DelayedFunctionCaller {
|
class DelayedFunctionCaller {
|
||||||
final void Function() function;
|
final void Function() function;
|
||||||
final Duration duration;
|
final Duration duration;
|
||||||
|
final bool resetTimerOnCall;
|
||||||
Timer? _timer;
|
Timer? _timer;
|
||||||
|
|
||||||
DelayedFunctionCaller(this.function, this.duration);
|
DelayedFunctionCaller(this.function, this.duration,
|
||||||
|
{this.resetTimerOnCall = false});
|
||||||
|
|
||||||
get scheduled => _timer != null && _timer!.isActive;
|
get scheduled => _timer != null && _timer!.isActive;
|
||||||
|
|
||||||
void call() {
|
void call() {
|
||||||
// If a timer is already active, return.
|
|
||||||
if (_timer != null && _timer!.isActive) {
|
if (_timer != null && _timer!.isActive) {
|
||||||
return;
|
// If a timer is already active and we don't want to reset it, return.
|
||||||
|
if (!resetTimerOnCall) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_timer!.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a timer that calls the function after the specified duration.
|
// Create a timer that calls the function after the specified duration.
|
||||||
|
|
|
@ -6,13 +6,16 @@ import 'package:release_schedule/model/movie_manager.dart';
|
||||||
class LiveSearch extends ChangeNotifier {
|
class LiveSearch extends ChangeNotifier {
|
||||||
String searchTerm = "";
|
String searchTerm = "";
|
||||||
List<MovieData> searchResults = [];
|
List<MovieData> searchResults = [];
|
||||||
Duration minTimeBetweenRequests = const Duration(milliseconds: 200);
|
|
||||||
late final DelayedFunctionCaller _searchCaller;
|
late final DelayedFunctionCaller _searchCaller;
|
||||||
final MovieManager manager;
|
final MovieManager manager;
|
||||||
bool searchingOnline = false;
|
bool searchingOnline = false;
|
||||||
|
|
||||||
LiveSearch(this.manager) {
|
LiveSearch(this.manager) {
|
||||||
_searchCaller = DelayedFunctionCaller(searchOnline, minTimeBetweenRequests);
|
_searchCaller = DelayedFunctionCaller(
|
||||||
|
searchOnline,
|
||||||
|
const Duration(milliseconds: 750),
|
||||||
|
resetTimerOnCall: true,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get loading => searchingOnline || _searchCaller.scheduled;
|
get loading => searchingOnline || _searchCaller.scheduled;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:release_schedule/model/date_format.dart';
|
|
||||||
import 'package:release_schedule/model/movie.dart';
|
import 'package:release_schedule/model/movie.dart';
|
||||||
import 'package:release_schedule/view/movie_page.dart';
|
import 'package:release_schedule/view/movie_page.dart';
|
||||||
|
|
||||||
|
@ -14,8 +13,7 @@ class MovieItem extends StatelessWidget {
|
||||||
builder: (context, widget) {
|
builder: (context, widget) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(movie.title),
|
title: Text(movie.title),
|
||||||
subtitle: Text(
|
subtitle: Text(movie.genres?.join(", ") ?? ""),
|
||||||
"${dateRelativeToNow(movie.releaseDate.date)}, ${movie.releaseDate.toString()}, ${movie.genres?.join(", ") ?? ""}"),
|
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: Icon(movie.bookmarked
|
icon: Icon(movie.bookmarked
|
||||||
? Icons.bookmark_added
|
? Icons.bookmark_added
|
||||||
|
|
|
@ -24,9 +24,6 @@ void main() {
|
||||||
|
|
||||||
expect(find.text('Test Movie'), findsOneWidget);
|
expect(find.text('Test Movie'), findsOneWidget);
|
||||||
|
|
||||||
final formattedDate = movie.releaseDate.toString();
|
|
||||||
expect(find.textContaining(formattedDate), findsOneWidget);
|
|
||||||
|
|
||||||
expect(find.textContaining('Action, Adventure'), findsOneWidget);
|
expect(find.textContaining('Action, Adventure'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue