Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/pages/reader/epub_reader/epub_reader_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:kover/utils/constants/kover_icons.dart';
import 'package:kover/utils/layout_constants.dart';
import 'package:kover/widgets/settings/boolean_option.dart';
import 'package:kover/widgets/settings/choice_option.dart';
import 'package:kover/widgets/settings/dim_option.dart';
import 'package:kover/widgets/settings/numeric_option.dart';
import 'package:kover/widgets/util/async_value.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
Expand Down Expand Up @@ -91,6 +92,7 @@ class EpubReaderSettingsBottomSheet extends ConsumerWidget {
.read(provider.notifier)
.setMarginSize(newValue),
),
const DimOption(),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to have it in a position generally similar across the readers, probably right above the show progress bar would be best


NumericOption(
title: 'Line Height',
Expand Down
2 changes: 2 additions & 0 deletions lib/pages/reader/image_reader/image_reader_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:kover/utils/constants/kover_icons.dart';
import 'package:kover/utils/layout_constants.dart';
import 'package:kover/widgets/settings/boolean_option.dart';
import 'package:kover/widgets/settings/choice_option.dart';
import 'package:kover/widgets/settings/dim_option.dart';
import 'package:kover/widgets/settings/numeric_option.dart';
import 'package:kover/widgets/util/async_value.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';
Expand Down Expand Up @@ -150,6 +151,7 @@ class ImageReaderSettingsBottomSheet extends ConsumerWidget {
.read(provider.notifier)
.setVerticalReaderPadding(newValue),
),
const DimOption(),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Places here it would only be shown when the image reader is in vertical mode ;)

Would personally place it above the ignore safe areas here as to keep the two toggles close.

NumericOption(
title: 'Vertical Gap',
icon: LucideIcons.unfoldVertical,
Expand Down
41 changes: 31 additions & 10 deletions lib/pages/reader/overlay/reader_overlay.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import 'package:kover/riverpod/providers/reader//reader.dart';
import 'package:kover/riverpod/providers/reader/epub_reader.dart';
import 'package:kover/riverpod/providers/reader/reader_navigation.dart';
import 'package:kover/riverpod/providers/router.dart';
import 'package:kover/riverpod/providers/settings/reader_dim_settings.dart';
import 'package:kover/utils/layout_constants.dart';
import 'package:kover/utils/logging.dart';
import 'package:kover/widgets/util/async_value.dart';
Expand Down Expand Up @@ -95,6 +96,13 @@ class ReaderOverlay extends HookConsumerWidget {
),
);

final dimLevel = ref
.watch(readerDimSettingsProvider)
.maybeWhen(
data: (state) => state.dimLevel,
orElse: () => 0.0,
);

ref.listen(
readerNavigationProvider(
seriesId: seriesId,
Expand Down Expand Up @@ -141,21 +149,36 @@ class ReaderOverlay extends HookConsumerWidget {
},
child: Stack(
children: [
Positioned.fill(
child: Column(
mainAxisSize: .min,
children: [
Expanded(child: child),
if (showProgressBar && state.series.format == .epub)
Positioned.fill(child: child),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a more elegant approach could be to extract the responsibility to a thin consumer widget which would watch the setting and apply the opacity to the child widget. That way the child could be wrapped within the Column and would not require the additional branch conditions for the progress bar, what do you think?

if (dimLevel > 0)
Positioned.fill(
child: IgnorePointer(
child: ColoredBox(
color: Color.fromRGBO(0, 0, 0, dimLevel),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it work to just manipulate the child opacity through either an AnimatedOpacity or flutter_animate opacity animation?

If not it could still be moved to a nested stack in the dedicated widget I think to avoid additional complexity in this already quite cluttered tree

),
),
),
if (showProgressBar && state.series.format == .epub)
Positioned(
bottom: 0,
left: 0,
right: 0,
child:
SubpageProgress(
seriesId: seriesId,
chapterId: chapterId,
)
.animate(
target: uiVisible.value ? 0.0 : 1.0,
)
.fadeIn(duration: 200.ms)
else if (showProgressBar)
.fadeIn(duration: 200.ms),
)
else if (showProgressBar)
Positioned(
bottom: 0,
left: 0,
right: 0,
child:
ReaderProgress(
seriesId: seriesId,
chapterId: chapterId,
Expand All @@ -164,9 +187,7 @@ class ReaderOverlay extends HookConsumerWidget {
target: uiVisible.value ? 0.0 : 1.0,
)
.fadeIn(duration: 200.ms),
],
),
),
Positioned.fill(
child: Row(
children: [
Expand Down
2 changes: 2 additions & 0 deletions lib/pages/reader/pdf_reader/pdf_reader_controls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:kover/utils/constants/kover_icons.dart';
import 'package:kover/utils/layout_constants.dart';
import 'package:kover/widgets/settings/boolean_option.dart';
import 'package:kover/widgets/settings/choice_option.dart';
import 'package:kover/widgets/settings/dim_option.dart';
import 'package:kover/widgets/util/async_value.dart';

class PdfReaderSettingsBottomSheet extends ConsumerWidget {
Expand Down Expand Up @@ -110,6 +111,7 @@ class PdfReaderSettingsBottomSheet extends ConsumerWidget {
.setShowProgressBar(newValue);
},
),
const DimOption(),

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this one to be moved to whatever the final position in the list will be

],
),
),
Expand Down
71 changes: 71 additions & 0 deletions lib/riverpod/providers/settings/reader_dim_settings.dart

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea in general for it to be a more generic setting, though for all other reader ones they're stored per series with the possibility of overriding the defaults. Since this will ultimately live in the same settings lists I think that behavior should be kept or it may become confusing. So far I just duplicated the setting in all respective models to avoid dealing with rippling the default overriding and resetting.

I think it could either accept a series ID and have the defaults logic rippling and potentially find some elegant pattern that could be applied to the other common parameter, or be "duplicated" to the respective model while keeping the limits constants to somewhere central.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hooks_riverpod/experimental/persist.dart';
import 'package:kover/riverpod/repository/storage_repository.dart';
import 'package:kover/utils/logging.dart';
import 'package:riverpod_annotation/experimental/json_persist.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'reader_dim_settings.freezed.dart';
part 'reader_dim_settings.g.dart';

sealed class ReaderDimSettingsLimits {
static const double dimMin = 0.0;
static const double dimMax = 0.9;
static const double dimStep = 5.0;
}

@freezed
sealed class ReaderDimSettingsState with _$ReaderDimSettingsState {
const ReaderDimSettingsState._();
const factory ReaderDimSettingsState({
@Default(0.0) double dimLevel,
}) = _ReaderDimSettingsState;

factory ReaderDimSettingsState.fromJson(Map<String, Object?> json) =>
_$ReaderDimSettingsStateFromJson(json);
}

@riverpod
@JsonPersist()
class ReaderDimSettings extends _$ReaderDimSettings {
@override
Future<ReaderDimSettingsState> build() async {
await persist(
ref.watch(storageProvider.future),
options: const StorageOptions(cacheTime: StorageCacheTime.unsafe_forever),
).future;
return state.value ?? const ReaderDimSettingsState();
}

Future<void> adjustDimLevel(double delta) async {
final current = await future;
state = AsyncData(
current.copyWith(
dimLevel: (current.dimLevel + delta).clamp(
ReaderDimSettingsLimits.dimMin,
ReaderDimSettingsLimits.dimMax,
),
),
);
log.info(
'adjust dim level',
attributes: {'value': .double(state.value!.dimLevel)},
);
}

Future<void> setDimLevel(double level) async {
final current = await future;
state = AsyncData(
current.copyWith(
dimLevel: level.clamp(
ReaderDimSettingsLimits.dimMin,
ReaderDimSettingsLimits.dimMax,
),
),
);
log.info(
'set dim level',
attributes: {'value': .double(level)},
);
}
}
32 changes: 32 additions & 0 deletions lib/widgets/settings/dim_option.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:kover/riverpod/providers/settings/reader_dim_settings.dart';
import 'package:kover/widgets/settings/numeric_option.dart';
import 'package:lucide_icons_flutter/lucide_icons.dart';

class DimOption extends ConsumerWidget {
const DimOption({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
final dimLevel = ref
.watch(readerDimSettingsProvider)
.maybeWhen(
data: (state) => state.dimLevel,
orElse: () => 0.0,
);

return NumericOption(
title: 'Screen Dimming',
icon: LucideIcons.sunMedium,
value: dimLevel * 100,
min: 0,
max: 90,
step: ReaderDimSettingsLimits.dimStep,
decimalPlaces: 0,
onChanged: (newValue) => ref
.read(readerDimSettingsProvider.notifier)
.setDimLevel(newValue / 100),
);
}
}