add version field, installable app caching

This commit is contained in:
Andrew 2022-09-13 11:45:10 +07:00
parent 4833b5c18c
commit 2141e144be
7 changed files with 79 additions and 9 deletions

View file

@ -9,17 +9,47 @@ part 'scoop_search_event.dart';
part 'scoop_search_state.dart';
class ScoopSearchBloc extends Bloc<ScoopSearchEvent, ScoopSearchState> {
final Map<String, List<ScoopAppModel>> _cachedApps = {};
ScoopSearchBloc() : super(ScoopSearchInitial()) {
on<ScoopSearchReload>(
(event, emit) async {
_cachedApps.clear();
try {
Map<String, List<ScoopAppModel>> data = await getAllInstallableApps();
_cachedApps.addAll(data);
emit(ScoopSearchLoaded(data));
} catch (e) {
emit(const ScoopSearchLoaded({}));
}
},
transformer: droppable(),
);
on<ScoopSearchQueryChanged>(
(event, emit) async {
emit(ScoopSearchLoading());
try {
Map<String, List<ScoopAppModel>> data = {};
if (event.query.isEmpty) {
data = await getAllInstallableApps();
if (_cachedApps.isEmpty) {
_cachedApps.addAll(await getAllInstallableApps());
}
if (event.query.isNotEmpty) {
for (final bucket in _cachedApps.keys) {
data[bucket] = _cachedApps[bucket]
?.where((app) =>
app.name
.toLowerCase()
.contains(event.query.toLowerCase()) ||
app.description
.toLowerCase()
.contains(event.query.toLowerCase()))
.toList() ??
[];
}
} else {
data = await searchInstallableApps(event.query);
data.addAll(_cachedApps);
}
emit(ScoopSearchLoaded(data));
} catch (e) {

View file

@ -7,6 +7,8 @@ abstract class ScoopSearchEvent extends Equatable {
List<Object> get props => [];
}
class ScoopSearchReload extends ScoopSearchEvent {}
class ScoopSearchQueryChanged extends ScoopSearchEvent {
final String query;

View file

@ -31,8 +31,7 @@ void main() async {
create: (context) => ScoopListBloc()..add(ScoopLocate()),
),
BlocProvider(
create: (context) =>
ScoopSearchBloc()..add(const ScoopSearchQueryChanged("")),
create: (context) => ScoopSearchBloc()..add(ScoopSearchReload()),
),
],
child: const LadleApp(),

View file

@ -4,6 +4,8 @@ class ScoopAppModel extends Equatable {
final String name;
final String description;
final String bucket;
final String homepage;
final String version;
final DateTime updatedAt;
const ScoopAppModel({
@ -11,8 +13,11 @@ class ScoopAppModel extends Equatable {
required this.description,
required this.bucket,
required this.updatedAt,
required this.homepage,
required this.version,
});
@override
List<Object?> get props => [name, description, bucket, updatedAt];
List<Object?> get props =>
[name, description, bucket, homepage, version, updatedAt];
}

View file

@ -9,6 +9,7 @@ import 'package:ladle/models/scoop_app_model.dart';
import 'package:ladle/utils/scoop_utils.dart';
import 'package:ladle/utils/set_extension.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../bloc/scoop_list_bloc.dart';
@ -218,7 +219,14 @@ class _AppSearchFragmentState extends State<AppSearchFragment> {
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(appModel.name).fontSize(32).bold().paddingDirectional(bottom: 16),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(appModel.name).fontSize(32).bold(),
Text(appModel.version).padding(all: 4)
],
).paddingDirectional(bottom: 16),
Row(
children: [
Chip(
@ -251,6 +259,15 @@ class _AppSearchFragmentState extends State<AppSearchFragment> {
},
),
],
).paddingDirectional(bottom: 8),
Row(
children: [
OutlinedButton(
child: const Text("Homepage"),
onPressed: () {
launchUrlString(appModel.homepage);
}).padding(right: 8),
],
).paddingDirectional(bottom: 16),
Text(
appModel.description,

View file

@ -1,6 +1,7 @@
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:ladle/bloc/scoop_search_bloc.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:url_launcher/url_launcher.dart';
@ -92,8 +93,10 @@ class _HomePageState extends State<HomePage> {
),
onPressed: state is ScoopListLoading
? null
: () =>
context.read<ScoopListBloc>().add(ScoopUpdateRequested()),
: () {
context.read<ScoopListBloc>().add(ScoopUpdateRequested());
context.read<ScoopSearchBloc>().add(ScoopSearchReload());
},
),
WindowButton(
iconBuilder: (buttonContext) => const Icon(

View file

@ -50,6 +50,8 @@ Future<Map<String, List<ScoopAppModel>>> searchInstallableApps(
String appName =
file.path.split("\\").last.replaceAll(RegExp(r"\.(json|ya?ml)"), "");
String appDescription = data["description"] ?? "No description";
String appHomepage = data["homepage"] ?? "";
String appVersion = data["version"] ?? "0.0.0";
DateTime appUpdatedAt = await file.lastModified();
if (appName.toLowerCase().contains(query.toLowerCase()) ||
@ -58,6 +60,8 @@ Future<Map<String, List<ScoopAppModel>>> searchInstallableApps(
name: appName,
description: appDescription,
bucket: bucket,
homepage: appHomepage,
version: appVersion,
updatedAt: appUpdatedAt,
));
}
@ -91,12 +95,16 @@ Future<Map<String, List<ScoopAppModel>>> getAllInstallableApps() async {
String appName =
file.path.split("\\").last.replaceAll(RegExp(r"\.(json|ya?ml)"), "");
String appDescription = data["description"] ?? "No description";
String appHomepage = data["homepage"] ?? "";
String appVersion = data["version"] ?? "0.0.0";
DateTime appUpdatedAt = await file.lastModified();
apps.add(ScoopAppModel(
name: appName,
description: appDescription,
bucket: bucket,
homepage: appHomepage,
version: appVersion,
updatedAt: appUpdatedAt,
));
}
@ -117,12 +125,16 @@ Future<List<ScoopAppModel>> getInstalledScoopApps() async {
String appName = element.path.split("\\").last;
String appDescription = "No description";
String appBucket = "UNKNOWN";
String appHomepage = "";
String appVersion = "0.0.0";
DateTime appUpdatedAt = DateTime.fromMicrosecondsSinceEpoch(0);
final manifestFile = File("${element.path}/current/manifest.json");
if (await manifestFile.exists()) {
final manifestData = jsonDecode(await manifestFile.readAsString());
appDescription = manifestData["description"] ?? appDescription;
appHomepage = manifestData["homepage"] ?? appHomepage;
appVersion = manifestData["version"] ?? appVersion;
appUpdatedAt = await manifestFile.lastModified();
}
@ -136,6 +148,8 @@ Future<List<ScoopAppModel>> getInstalledScoopApps() async {
name: appName,
description: appDescription,
bucket: appBucket,
homepage: appHomepage,
version: appVersion,
updatedAt: appUpdatedAt,
));
}