remove unnecessary safearea

This commit is contained in:
Fabian Freund
2024-06-16 21:15:50 +02:00
parent 33d6121053
commit 11e3b9c0a1
2 changed files with 334 additions and 342 deletions
@@ -25,44 +25,41 @@ class ChatArchiveListScreen extends HookConsumerWidget {
),
],
),
body: SafeArea(
child: Skeletonizer(
enabled: chatsAsync.isLoading,
child: chatsAsync.when(
data: (chats) {
return ListView.builder(
itemCount: chats.length,
itemBuilder: (context, index) {
final chat = chats[index];
body: Skeletonizer(
enabled: chatsAsync.isLoading,
child: chatsAsync.when(
data: (chats) {
return ListView.builder(
itemCount: chats.length,
itemBuilder: (context, index) {
final chat = chats[index];
return ListTile(
title: Text(chat.toString()),
subtitle: (chat.dateTime != null)
? Text(chat.dateTime!.formatWithMinutePrecision())
: null,
onTap: () async {
await context.push(
ChatArchiveDetailRoute(fileName: chat.fileName)
.location,
);
},
);
},
);
},
error: (error, stackTrace) {
return FailureWidget(
title: 'Could not load archived chats',
exception: error,
onRetry: () => ref.refresh(chatArchiveRepositoryProvider),
);
},
loading: () => ListView.builder(
itemCount: 3,
itemBuilder: (context, index) => const ListTile(
title: Bone.text(),
subtitle: Bone.text(),
),
return ListTile(
title: Text(chat.toString()),
subtitle: (chat.dateTime != null)
? Text(chat.dateTime!.formatWithMinutePrecision())
: null,
onTap: () async {
await context.push(
ChatArchiveDetailRoute(fileName: chat.fileName).location,
);
},
);
},
);
},
error: (error, stackTrace) {
return FailureWidget(
title: 'Could not load archived chats',
exception: error,
onRetry: () => ref.refresh(chatArchiveRepositoryProvider),
);
},
loading: () => ListView.builder(
itemCount: 3,
itemBuilder: (context, index) => const ListTile(
title: Bone.text(),
subtitle: Bone.text(),
),
),
),
@@ -90,332 +90,327 @@ class SettingsScreen extends HookConsumerWidget {
return Scaffold(
appBar: AppBar(title: const Text('Settings')),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
_buildSection(theme, 'Kagi'),
Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 8,
),
child: TextField(
enableIMEPersonalizedLearning: false,
autocorrect: false,
controller: kagiSessionTextController,
obscureText: hideSessionText.value,
decoration: InputDecoration(
label: const Text('Kagi Session Token'),
hintText: 'https://kagi.com/search?token=...',
helperMaxLines: 2,
helper: Markdown(
shrinkWrap: true,
padding: EdgeInsets.zero,
data:
'You can visit your [Kagi Account Settings](user_details) to get your Session Link.',
onTapLink: (text, href, title) async {
if (href == 'user_details') {
await ui_helper.launchUrlFeedback(
context,
Uri.parse(
'https://kagi.com/settings?p=user_details',
),
);
}
},
),
suffixIcon: IconButton(
onPressed: () {
hideSessionText.value = !hideSessionText.value;
},
icon: Icon(
hideSessionText.value
? Icons.visibility
: Icons.visibility_off,
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: [
_buildSection(theme, 'Kagi'),
Padding(
padding: const EdgeInsets.only(
left: 16,
right: 16,
bottom: 8,
),
child: TextField(
enableIMEPersonalizedLearning: false,
autocorrect: false,
controller: kagiSessionTextController,
obscureText: hideSessionText.value,
decoration: InputDecoration(
label: const Text('Kagi Session Token'),
hintText: 'https://kagi.com/search?token=...',
helperMaxLines: 2,
helper: Markdown(
shrinkWrap: true,
padding: EdgeInsets.zero,
data:
'You can visit your [Kagi Account Settings](user_details) to get your Session Link.',
onTapLink: (text, href, title) async {
if (href == 'user_details') {
await ui_helper.launchUrlFeedback(
context,
Uri.parse(
'https://kagi.com/settings?p=user_details',
),
);
}
},
),
suffixIcon: IconButton(
onPressed: () {
hideSessionText.value = !hideSessionText.value;
},
icon: Icon(
hideSessionText.value
? Icons.visibility
: Icons.visibility_off,
),
),
),
),
SwitchListTile.adaptive(
title: const Text('Show Early Access Features'),
subtitle: const Text(
"Displays Kagi's early access features in the UI. As an Ultimate subscriber, you will likely want to have this enabled.",
),
value: showEarlyAccessFeatures,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) => currentSettings.copyWith
.showEarlyAccessFeatures(value),
);
),
SwitchListTile.adaptive(
title: const Text('Show Early Access Features'),
subtitle: const Text(
"Displays Kagi's early access features in the UI. As an Ultimate subscriber, you will likely want to have this enabled.",
),
value: showEarlyAccessFeatures,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) => currentSettings.copyWith
.showEarlyAccessFeatures(value),
);
},
),
const SizedBox(
height: 16,
),
_buildSection(theme, 'General'),
SwitchListTile.adaptive(
title: const Text('Incognito Mode'),
subtitle: const Text(
'Deletes all browsing data upon app restart for enhanced privacy.',
),
value: incognitoEnabled,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.incognitoMode(value),
);
},
),
SwitchListTile.adaptive(
title: const Text('Enable JavaScript'),
subtitle: const Text(
'While turning off JavaScript boosts security, privacy, and speed, it may cause some sites to not work as intended.',
),
value: javacsriptEnabled,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.enableJavascript(value),
);
},
),
SwitchListTile.adaptive(
title: const Text('Launch Links Externally'),
subtitle: const Text(
'Opens all links (except for kagi.com) in your default browser.',
),
value: launchUrlExternal,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.launchUrlExternal(value),
);
},
),
const SizedBox(
height: 16,
),
_buildSection(theme, 'Bangs'),
ButtonListTile(
title: 'Bang Frequencies',
subtitle: 'Tracked usage for Bang recommendations',
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangDataRepositoryProvider.notifier)
.clearFrequency();
},
icon: const Icon(Icons.delete),
label: const Text('Clear'),
),
const SizedBox(
height: 16,
),
_buildSection(theme, 'General'),
SwitchListTile.adaptive(
title: const Text('Incognito Mode'),
subtitle: const Text(
'Deletes all browsing data upon app restart for enhanced privacy.',
),
value: incognitoEnabled,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.incognitoMode(value),
);
},
),
SwitchListTile.adaptive(
title: const Text('Enable JavaScript'),
subtitle: const Text(
'While turning off JavaScript boosts security, privacy, and speed, it may cause some sites to not work as intended.',
),
value: javacsriptEnabled,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.enableJavascript(value),
);
},
),
SwitchListTile.adaptive(
title: const Text('Launch Links Externally'),
subtitle: const Text(
'Opens all links (except for kagi.com) in your default browser.',
),
value: launchUrlExternal,
onChanged: (value) async {
await ref.read(saveSettingsControllerProvider.notifier).save(
(currentSettings) =>
currentSettings.copyWith.launchUrlExternal(value),
);
},
),
const SizedBox(
height: 16,
),
_buildSection(theme, 'Bangs'),
ButtonListTile(
title: 'Bang Frequencies',
subtitle: 'Tracked usage for Bang recommendations',
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangDataRepositoryProvider.notifier)
.clearFrequency();
},
icon: const Icon(Icons.delete),
label: const Text('Clear'),
),
),
Consumer(
builder: (context, ref, child) {
final size = ref.watch(
bangIconCacheSizeMegabytesProvider.select(
(value) => value.valueOrNull,
),
);
),
Consumer(
builder: (context, ref, child) {
final size = ref.watch(
bangIconCacheSizeMegabytesProvider.select(
(value) => value.valueOrNull,
),
);
return ButtonListTile(
title: 'Icon Cache',
subtitle: 'Stored favicons for Bangs',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Size'),
Text('${size?.toStringAsFixed(2) ?? 0} MB'),
],
),
],
),
return ButtonListTile(
title: 'Icon Cache',
subtitle: 'Stored favicons for Bangs',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Size'),
Text('${size?.toStringAsFixed(2) ?? 0} MB'),
],
),
],
),
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangDataRepositoryProvider.notifier)
.clearIconData();
},
icon: const Icon(Icons.delete),
label: const Text('Clear'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.general).select(
(value) => value.valueOrNull,
),
);
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangDataRepositoryProvider.notifier)
.clearIconData();
},
icon: const Icon(Icons.delete),
label: const Text('Clear'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.general).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.general).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.general).select(
(value) => value.valueOrNull,
),
);
return ButtonListTile(
title: 'General Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ??
'N/A',
),
],
),
],
),
return ButtonListTile(
title: 'General Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ?? 'N/A',
),
],
),
],
),
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncGeneralBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.assistant).select(
(value) => value.valueOrNull,
),
);
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncGeneralBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.assistant).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.assistant).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.assistant).select(
(value) => value.valueOrNull,
),
);
return ButtonListTile(
title: 'Assistant Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ??
'N/A',
),
],
),
],
),
return ButtonListTile(
title: 'Assistant Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ?? 'N/A',
),
],
),
],
),
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncAssistantBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.kagi).select(
(value) => value.valueOrNull,
),
);
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncAssistantBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
Consumer(
builder: (context, ref, child) {
final lastSync = ref.watch(
lastSyncOfGroupProvider(BangGroup.kagi).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.kagi).select(
(value) => value.valueOrNull,
),
);
final count = ref.watch(
bangCountOfGroupProvider(BangGroup.kagi).select(
(value) => value.valueOrNull,
),
);
return ButtonListTile(
title: 'Kagi Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ??
'N/A',
),
],
),
],
),
return ButtonListTile(
title: 'Kagi Bangs',
subtitle: 'Automatically syncs every 7 days',
content: Padding(
padding: const EdgeInsets.only(top: 8.0),
child: DefaultTextStyle(
style: GoogleFonts.robotoMono(),
child: Table(
children: [
TableRow(
children: [
const Text('Entries'),
Text(count?.toString() ?? 'N/A'),
],
),
TableRow(
children: [
const Text('Last Sync'),
Text(
lastSync?.formatWithMinutePrecision() ?? 'N/A',
),
],
),
],
),
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncKagiBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
],
),
),
button: FilledButton.icon(
onPressed: () async {
await ref
.read(bangSyncRepositoryProvider.notifier)
.syncKagiBangs();
},
icon: const Icon(Icons.sync),
label: const Text('Sync'),
),
);
},
),
],
),
),
);