Minor UI fixes

This commit is contained in:
franzap
2024-10-21 16:54:22 -03:00
parent 83d677dced
commit c04449eb43
7 changed files with 68 additions and 26 deletions
+6 -3
View File
@@ -10,7 +10,6 @@ import 'package:zapstore/main.data.dart';
import 'package:zapstore/models/app.dart';
import 'package:zapstore/models/release.dart';
import 'package:zapstore/utils/extensions.dart';
import 'package:zapstore/widgets/app_card.dart';
import 'package:zapstore/widgets/install_button.dart';
import 'package:zapstore/widgets/release_card.dart';
import 'package:zapstore/widgets/signer_and_developer_row.dart';
@@ -221,7 +220,11 @@ class AppDetailScreen extends HookConsumerWidget {
.then((match) {
if (match != null && !match) {
context.showError(
'APK certificate mismatch!\nPlease report');
title:
'APK certificate mismatch!',
description:
'Please let us know',
);
}
});
},
@@ -268,7 +271,7 @@ class AppDetailScreen extends HookConsumerWidget {
SizedBox(
height: 50,
child: Center(
child: InstallButton(app: app, disabled: !app.signer.isPresent),
child: InstallButton(app: app),
),
),
],
+19 -2
View File
@@ -1,3 +1,6 @@
import 'dart:math';
import 'package:dart_emoji/dart_emoji.dart';
import 'package:flutter/material.dart';
import 'package:flutter_data/flutter_data.dart';
import 'package:toastification/toastification.dart';
@@ -21,18 +24,19 @@ extension ContextX on BuildContext {
);
}
void showError(String message, {Icon? icon}) {
void showError({required String title, String? description, Icon? icon}) {
toastification.show(
context: this,
type: ToastificationType.error,
style: ToastificationStyle.fillColored,
icon: icon ?? Icon(Icons.error),
title: Text(
message,
title,
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
showProgressBar: false,
closeOnClick: true,
description: description != null ? Text(description) : null,
alignment: Alignment.lerp(Alignment.bottomCenter, Alignment.center, 0.25),
);
}
@@ -46,4 +50,17 @@ HasMany<T> hasMany<T extends DataModelMixin<T>>(Map<String, dynamic> map) {
return HasMany<T>.fromJson(map);
}
extension StringWidget on String {
static final _emojiParser = EmojiParser();
String parseEmojis() {
return replaceAllMapped(RegExp(':([a-z]*):'), (m) {
return _emojiParser.hasName(m[1]!) ? _emojiParser.get(m[1]!).code : m[0]!;
});
}
String substringMin(int size) {
return substring(0, min(length, 80));
}
}
const kI = "e593c54f840b32054dcad0fac15d57e4ac6523e31fe26b3087de6b07a2e9af58";
+1 -10
View File
@@ -1,5 +1,4 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:dart_emoji/dart_emoji.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
@@ -9,6 +8,7 @@ import 'package:skeletonizer/skeletonizer.dart';
import 'package:zapstore/main.data.dart';
import 'package:zapstore/models/app.dart';
import 'package:zapstore/models/local_app.dart';
import 'package:zapstore/utils/extensions.dart';
import 'package:zapstore/widgets/author_container.dart';
import 'package:zapstore/widgets/install_button.dart';
import 'package:zapstore/widgets/pill_widget.dart';
@@ -267,12 +267,3 @@ class TagsContainer extends StatelessWidget {
);
}
}
extension StringWidget on String {
static final _emojiParser = EmojiParser();
String parseEmojis() {
return replaceAllMapped(RegExp(':([a-z]*):'), (m) {
return _emojiParser.hasName(m[1]!) ? _emojiParser.get(m[1]!).code : m[0]!;
});
}
}
+4 -2
View File
@@ -81,8 +81,10 @@ class LoginContainer extends HookConsumerWidget {
.findOne(controller.text.trim())
.then((user) {
ref.settings.findOneLocalById('_')!.user.value = user;
}).catchError((e) {
context.showError(e.message ?? e.toString());
}).catchError((e, stack) {
context.showError(
title: e.message ?? e.toString(),
description: stack?.toString().substringMin(200));
});
},
builder: (context, child, callback, buttonState) {
+2 -1
View File
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_data/flutter_data.dart';
@@ -49,7 +50,7 @@ class ErrorContainer extends HookConsumerWidget {
),
Gap(6),
Text(
'${stack?.toString().substring(0, 80)}',
stack?.toString().substringMin(80) ?? '',
style: TextStyle(
fontSize: 12,
color: Colors.grey,
+28
View File
@@ -0,0 +1,28 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:zapstore/models/app.dart';
import 'package:zapstore/widgets/app_card.dart';
class HorizontalGrid extends StatelessWidget {
final List<App> apps;
HorizontalGrid({super.key, required this.apps});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 230,
child: GridView.builder(
scrollDirection: Axis.horizontal,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.15,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: apps.isEmpty ? 8 : apps.length,
itemBuilder: (context, i) => TinyAppCard(app: apps.elementAtOrNull(i)),
),
);
}
}
+8 -8
View File
@@ -18,10 +18,8 @@ class InstallButton extends ConsumerWidget {
super.key,
required this.app,
this.compact = false,
this.disabled = false,
});
final bool disabled;
final bool compact;
final App app;
@@ -38,10 +36,6 @@ class InstallButton extends ConsumerWidget {
},
_ => switch (progress) {
IdleInstallProgress() => () {
// show trust dialog only if first install
if (disabled) {
context.showError('Missing signer');
}
if (app.canInstall) {
showDialog(
context: context,
@@ -51,11 +45,15 @@ class InstallButton extends ConsumerWidget {
);
} else if (app.canUpdate) {
app.install();
} else {
context.showError(
title: 'Can\'t install',
description: 'Release or signer are missing.');
}
},
ErrorInstallProgress(:final e) => () {
// show error and reset state to idle
context.showError((e as dynamic).message);
context.showError(title: (e as dynamic).message);
ref.read(installationProgressProvider(app.id!).notifier).state =
IdleInstallProgress();
},
@@ -99,7 +97,9 @@ class InstallButton extends ConsumerWidget {
fontWeight: FontWeight.bold),
),
)
: Text('Install'),
: (app.canInstall
? Text('Install')
: Text('Nothing to install')),
DownloadingInstallProgress(:final progress) => Text(
'${(progress * 100).floor()}%',
style: TextStyle(fontWeight: FontWeight.bold),