Bug fixes

This commit is contained in:
Juan Gilsanz Polo
2024-03-24 02:46:30 +01:00
parent 75aa31ad11
commit 822c65c4e6
3 changed files with 297 additions and 263 deletions

View File

@@ -57,124 +57,112 @@ class BookmarkItem extends ConsumerWidget {
padding: tabletMode ? const EdgeInsets.symmetric(horizontal: 8) : const EdgeInsets.all(0),
child: ClipRRect(
borderRadius: tabletMode ? BorderRadius.circular(28) : BorderRadius.circular(0),
child: ContextMenuWidget(
menuProvider: (request) => Menu(
children: [
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onReadUnread(bookmark)),
title: bookmark.unread == true
? t.bookmarks.bookmarkOptions.markAsRead
: t.bookmarks.bookmarkOptions.markAsUnread,
image: MenuImage.icon(
bookmark.unread == true ? Icons.mark_email_read_rounded : Icons.mark_as_unread_rounded,
),
),
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onArchiveUnarchive(bookmark)),
title: bookmark.isArchived == true
? t.bookmarks.bookmarkOptions.unarchive
: t.bookmarks.bookmarkOptions.archive,
image: MenuImage.icon(
bookmark.isArchived == true ? Icons.unarchive_rounded : Icons.archive_rounded,
),
),
Menu(
title: t.bookmarks.bookmarkOptions.shareOptions,
image: MenuImage.icon(Icons.share_rounded),
child: Builder(
builder: (context) {
return ContextMenuWidget(
menuProvider: (request) => Menu(
children: [
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onShareInternally(bookmark)),
title: bookmark.shared == true
? t.bookmarks.bookmarkOptions.unshareInternally
: t.bookmarks.bookmarkOptions.shareInternally,
image: MenuImage.icon(Icons.input_rounded),
callback: () => Future.delayed(_durationTime).then((value) => onReadUnread(bookmark)),
title: bookmark.unread == true
? t.bookmarks.bookmarkOptions.markAsRead
: t.bookmarks.bookmarkOptions.markAsUnread,
image: MenuImage.icon(
bookmark.unread == true ? Icons.mark_email_read_rounded : Icons.mark_as_unread_rounded,
),
),
MenuAction(
callback: () => Future.delayed(_durationTime).then(
(value) => Share.shareUri(Uri.parse(bookmark.url!)),
callback: () => Future.delayed(_durationTime).then((value) => onArchiveUnarchive(bookmark)),
title: bookmark.isArchived == true
? t.bookmarks.bookmarkOptions.unarchive
: t.bookmarks.bookmarkOptions.archive,
image: MenuImage.icon(
bookmark.isArchived == true ? Icons.unarchive_rounded : Icons.archive_rounded,
),
title: t.bookmarks.bookmarkOptions.shareThirdPartyApp,
image: MenuImage.icon(Icons.output_rounded),
),
Menu(
title: t.bookmarks.bookmarkOptions.shareOptions,
image: MenuImage.icon(Icons.share_rounded),
children: [
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onShareInternally(bookmark)),
title: bookmark.shared == true
? t.bookmarks.bookmarkOptions.unshareInternally
: t.bookmarks.bookmarkOptions.shareInternally,
image: MenuImage.icon(Icons.input_rounded),
),
MenuAction(
callback: () {
final box = context.findRenderObject() as RenderBox?;
Future.delayed(_durationTime).then(
(value) => Share.share(
bookmark.url!,
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
),
);
},
title: t.bookmarks.bookmarkOptions.shareThirdPartyApp,
image: MenuImage.icon(Icons.output_rounded),
),
],
),
MenuSeparator(),
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onEdit(bookmark)),
title: t.bookmarks.bookmarkOptions.edit,
image: MenuImage.icon(Icons.edit_rounded),
),
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onDelete(bookmark)),
title: t.bookmarks.bookmarkOptions.delete,
image: MenuImage.icon(Icons.delete_rounded),
attributes: const MenuActionAttributes(destructive: true),
),
],
),
MenuSeparator(),
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onEdit(bookmark)),
title: t.bookmarks.bookmarkOptions.edit,
image: MenuImage.icon(Icons.edit_rounded),
),
MenuAction(
callback: () => Future.delayed(_durationTime).then((value) => onDelete(bookmark)),
title: t.bookmarks.bookmarkOptions.delete,
image: MenuImage.icon(Icons.delete_rounded),
attributes: const MenuActionAttributes(destructive: true),
),
],
),
child: Material(
color: selected && tabletMode
? Theme.of(context).colorScheme.primaryContainer
: tileBackgroundColor ?? Theme.of(context).colorScheme.surface,
child: InkWell(
onTap: () => onSelect(bookmark),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
child: Material(
color: selected && tabletMode
? Theme.of(context).colorScheme.primaryContainer
: tileBackgroundColor ?? Theme.of(context).colorScheme.surface,
child: InkWell(
onTap: () => onSelect(bookmark),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (ref.watch(appStatusProvider).showFavicon == true)
Padding(
padding: const EdgeInsets.only(right: 8),
child: ref.watch(faviconStoreProvider).loadingFavicons == true
? ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Skeletonizer(
enabled: true,
ignoreContainers: true,
child: Container(
width: 16,
height: 16,
color: Colors.black,
),
),
)
: Builder(
builder: (context) {
final faviconItem = ref
.watch(faviconStoreProvider)
.favicons
.where((f) => f.url == bookmark.url!)
.toList();
if (faviconItem.isEmpty) return const SizedBox();
if (faviconItem[0].isSvg == true) {
return SvgPicture.network(
faviconItem[0].favicon,
width: 16,
height: 16,
placeholderBuilder: (context) => ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Skeletonizer(
enabled: true,
ignoreContainers: true,
child: Container(
width: 16,
height: 16,
color: Colors.black,
),
),
Row(
children: [
if (ref.watch(appStatusProvider).showFavicon == true)
Padding(
padding: const EdgeInsets.only(right: 8),
child: ref.watch(faviconStoreProvider).loadingFavicons == true
? ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Skeletonizer(
enabled: true,
ignoreContainers: true,
child: Container(
width: 16,
height: 16,
color: Colors.black,
),
);
} else {
return Image.network(
faviconItem[0].favicon,
width: 16,
height: 16,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress != null) {
return ClipRRect(
),
)
: Builder(
builder: (context) {
final faviconItem = ref
.watch(faviconStoreProvider)
.favicons
.where((f) => f.url == bookmark.url!)
.toList();
if (faviconItem.isEmpty) return const SizedBox();
if (faviconItem[0].isSvg == true) {
return SvgPicture.network(
faviconItem[0].favicon,
width: 16,
height: 16,
placeholderBuilder: (context) => ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Skeletonizer(
enabled: true,
@@ -185,154 +173,176 @@ class BookmarkItem extends ConsumerWidget {
color: Colors.black,
),
),
);
}
return child;
},
);
}
},
),
),
Expanded(
child: Text(
validateStrings(bookmark.title, bookmark.websiteTitle),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
),
);
} else {
return Image.network(
faviconItem[0].favicon,
width: 16,
height: 16,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress != null) {
return ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Skeletonizer(
enabled: true,
ignoreContainers: true,
child: Container(
width: 16,
height: 16,
color: Colors.black,
),
),
);
}
return child;
},
);
}
},
),
),
Expanded(
child: Text(
validateStrings(bookmark.title, bookmark.websiteTitle),
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
],
),
const SizedBox(height: 4),
Text(
validateStrings(bookmark.description, bookmark.websiteDescription),
maxLines: 3,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 4),
Row(
children: [
Expanded(
child: Text(
bookmark.tagNames?.map((tag) => "#$tag").join(" ") ?? '',
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
if (bookmark.shared == true) ...[
if (bookmark.tagNames?.isNotEmpty == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Row(
children: [
Icon(
Icons.share_rounded,
size: 12,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
const SizedBox(width: 4),
Text(
t.bookmarks.bookmarkOptions.shared,
style: TextStyle(
fontSize: 10,
color: Theme.of(context).colorScheme.onPrimaryContainer,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
if (bookmark.unread == true) ...[
if (bookmark.tagNames?.isNotEmpty == true || bookmark.shared == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Row(
children: [
Icon(
Icons.mark_as_unread_rounded,
size: 12,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
const SizedBox(width: 4),
Text(
t.bookmarks.bookmarkOptions.unread,
style: TextStyle(
fontSize: 10,
color: Theme.of(context).colorScheme.onPrimaryContainer,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
if (bookmark.dateModified != null) ...[
if (bookmark.unread == true ||
bookmark.shared == true ||
bookmark.tagNames?.isNotEmpty == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Text(
dateToString(bookmark.dateModified!),
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
],
),
],
),
const SizedBox(height: 4),
Text(
validateStrings(bookmark.description, bookmark.websiteDescription),
maxLines: 3,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: TextStyle(
fontSize: 14,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 4),
Row(
children: [
Expanded(
child: Text(
bookmark.tagNames?.map((tag) => "#$tag").join(" ") ?? '',
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
if (bookmark.shared == true) ...[
if (bookmark.tagNames?.isNotEmpty == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Row(
children: [
Icon(
Icons.share_rounded,
size: 12,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
const SizedBox(width: 4),
Text(
t.bookmarks.bookmarkOptions.shared,
style: TextStyle(
fontSize: 10,
color: Theme.of(context).colorScheme.onPrimaryContainer,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
if (bookmark.unread == true) ...[
if (bookmark.tagNames?.isNotEmpty == true || bookmark.shared == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6,
vertical: 2,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Theme.of(context).colorScheme.primaryContainer,
),
child: Row(
children: [
Icon(
Icons.mark_as_unread_rounded,
size: 12,
color: Theme.of(context).colorScheme.onPrimaryContainer,
),
const SizedBox(width: 4),
Text(
t.bookmarks.bookmarkOptions.unread,
style: TextStyle(
fontSize: 10,
color: Theme.of(context).colorScheme.onPrimaryContainer,
fontWeight: FontWeight.w700,
),
),
],
),
),
],
if (bookmark.dateModified != null) ...[
if (bookmark.unread == true ||
bookmark.shared == true ||
bookmark.tagNames?.isNotEmpty == true)
Container(
width: 1,
height: 12,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Theme.of(context).colorScheme.tertiary.withOpacity(0.3),
),
Text(
dateToString(bookmark.dateModified!),
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
],
),
],
),
),
),
),
),
);
},
),
),
);

View File

@@ -48,12 +48,12 @@ class WebViewScreen extends HookConsumerWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
bookmark.title != "" ? bookmark.title! : bookmark.websiteTitle!,
bookmark.title ?? bookmark.websiteTitle ?? "Website",
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 4),
Text(
bookmark.url!,
bookmark.url ?? "",
style: TextStyle(
fontSize: 12,
color: Theme.of(context).colorScheme.onSurfaceVariant,

View File

@@ -75,9 +75,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -97,9 +99,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -119,9 +123,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -139,9 +145,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -157,9 +165,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -179,9 +189,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -197,9 +209,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -212,9 +226,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -224,9 +240,11 @@ class ApiClientService {
return const ApiResponse(successful: true);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -242,9 +260,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -266,9 +286,11 @@ class ApiClientService {
return const ApiResponse(successful: true);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
@@ -284,9 +306,11 @@ class ApiClientService {
);
} on DioException {
return const ApiResponse(successful: false);
} catch (e, stackTrace) {
} on FormatException catch (e, stackTrace) {
Sentry.captureException(e, stackTrace: stackTrace);
return const ApiResponse(successful: false);
} catch (_) {
return const ApiResponse(successful: false);
}
}
}