import 'dart:collection'; import 'dart:io'; import 'package:equatable/equatable.dart'; import 'package:flutter_material_color_picker/flutter_material_color_picker.dart'; import 'package:hacki/models/displayable.dart'; import 'package:hacki/models/models.dart'; import 'package:hacki/styles/palette.dart'; abstract final class Preference extends Equatable with SettingsDisplayable { const Preference({required this.val}); final T val; String get key; Preference copyWith({required T? val}); static final List> allPreferences = UnmodifiableListView>( >[ // Order of these preferences does not matter. FetchModePreference(), CommentsOrderPreference(), FontPreference(), FontSizePreference(), TabOrderPreference(), StoryMarkingModePreference(), AppColorPreference(), DateFormatPreference(), const TextScaleFactorPreference(), // Order of items below matters and // reflects the order on settings screen. const DisplayModePreference(), const MetadataModePreference(), const StoryUrlModePreference(), // Divider. const MarkReadStoriesModePreference(), // Divider. const NotificationModePreference(), const AutoScrollModePreference(), const CollapseModePreference(), const ReaderModePreference(), const CustomTabPreference(), const ManualPaginationPreference(), const SwipeGesturePreference(), const HapticFeedbackPreference(), const EyeCandyModePreference(), const TrueDarkModePreference(), const DevMode(), ], ); @override List get props => [key]; } abstract final class BooleanPreference extends Preference { const BooleanPreference({required super.val}); } abstract final class IntPreference extends Preference { const IntPreference({required super.val}); } abstract final class DoublePreference extends Preference { const DoublePreference({required super.val}); } final class DevMode extends BooleanPreference { const DevMode({bool? val}) : super(val: val ?? _devModeDefaultValue); static const bool _devModeDefaultValue = false; @override DevMode copyWith({required bool? val}) { return DevMode(val: val); } @override String get key => 'devMode'; @override String get title => 'Dev Mode'; @override String get subtitle => ''; @override bool get isDisplayable => false; } final class SwipeGesturePreference extends BooleanPreference { const SwipeGesturePreference({bool? val}) : super(val: val ?? _swipeGestureModeDefaultValue); static const bool _swipeGestureModeDefaultValue = false; @override SwipeGesturePreference copyWith({required bool? val}) { return SwipeGesturePreference(val: val); } @override String get key => 'swipeGestureMode'; @override String get title => 'Swipe Gesture'; @override String get subtitle => '''enable swipe gesture for switching between tabs. If enabled, long press on Story tile to trigger the action menu.'''; } final class NotificationModePreference extends BooleanPreference { const NotificationModePreference({bool? val}) : super(val: val ?? _notificationModeDefaultValue); static const bool _notificationModeDefaultValue = true; @override NotificationModePreference copyWith({required bool? val}) { return NotificationModePreference(val: val); } @override String get key => 'notificationMode'; @override String get title => 'Notification on New Reply'; @override String get subtitle => '''Hacki scans for new replies to your 15 most recent comments or stories every 5 minutes while the app is running in the foreground.'''; } final class CollapseModePreference extends BooleanPreference { const CollapseModePreference({bool? val}) : super(val: val ?? _collapseModeDefaultValue); static const bool _collapseModeDefaultValue = true; @override CollapseModePreference copyWith({required bool? val}) { return CollapseModePreference(val: val); } @override String get key => 'collapseMode'; @override String get title => 'Tap Anywhere to Collapse'; @override String get subtitle => '''if disabled, tap on the top of comment tile to collapse.'''; } final class AutoScrollModePreference extends BooleanPreference { const AutoScrollModePreference({bool? val}) : super(val: val ?? _autoScrollModeDefaultValue); static const bool _autoScrollModeDefaultValue = false; @override AutoScrollModePreference copyWith({required bool? val}) { return AutoScrollModePreference(val: val); } @override String get key => 'autoScrollMode'; @override String get title => 'Auto-scroll on Collapsing'; @override String get subtitle => '''automatically scroll to next comment when you collapse a comment.'''; } /// The value deciding whether or not the story /// tile should display link preview. Defaults to true. final class DisplayModePreference extends BooleanPreference { const DisplayModePreference({bool? val}) : super(val: val ?? _displayModeDefaultValue); static const bool _displayModeDefaultValue = true; @override DisplayModePreference copyWith({required bool? val}) { return DisplayModePreference(val: val); } @override String get key => 'displayMode'; @override String get title => 'Complex Story Tile'; @override String get subtitle => 'show web preview in story tile.'; } final class MetadataModePreference extends BooleanPreference { const MetadataModePreference({bool? val}) : super(val: val ?? _metadataModeDefaultValue); static const bool _metadataModeDefaultValue = true; @override MetadataModePreference copyWith({required bool? val}) { return MetadataModePreference(val: val); } @override String get key => 'metadataMode'; @override String get title => 'Show Metadata'; @override String get subtitle => '''show number of comments and post date in story tile.'''; } final class StoryUrlModePreference extends BooleanPreference { const StoryUrlModePreference({bool? val}) : super(val: val ?? _storyUrlModeDefaultValue); static const bool _storyUrlModeDefaultValue = true; @override StoryUrlModePreference copyWith({required bool? val}) { return StoryUrlModePreference(val: val); } @override String get key => 'storyUrlMode'; @override String get title => 'Show Url'; @override String get subtitle => '''show url in story tile.'''; } final class ReaderModePreference extends BooleanPreference { const ReaderModePreference({bool? val}) : super(val: val ?? _readerModeDefaultValue); static const bool _readerModeDefaultValue = true; @override ReaderModePreference copyWith({required bool? val}) { return ReaderModePreference(val: val); } @override String get key => 'readerMode'; @override String get title => 'Use Reader'; @override String get subtitle => '''enter reader mode in Safari directly when it is available.'''; @override bool get isDisplayable => Platform.isIOS; } final class MarkReadStoriesModePreference extends BooleanPreference { const MarkReadStoriesModePreference({bool? val}) : super(val: val ?? _markReadStoriesModeDefaultValue); static const bool _markReadStoriesModeDefaultValue = true; @override MarkReadStoriesModePreference copyWith({required bool? val}) { return MarkReadStoriesModePreference(val: val); } @override String get key => 'markReadStoriesMode'; @override String get title => 'Mark Read Stories'; @override String get subtitle => 'grey out stories you have read.'; } final class EyeCandyModePreference extends BooleanPreference { const EyeCandyModePreference({bool? val}) : super(val: val ?? _eyeCandyModeDefaultValue); static const bool _eyeCandyModeDefaultValue = false; @override EyeCandyModePreference copyWith({required bool? val}) { return EyeCandyModePreference(val: val); } @override String get key => 'eyeCandyMode'; @override String get title => 'Eye Candy'; @override String get subtitle => 'some sort of magic.'; } final class ManualPaginationPreference extends BooleanPreference { const ManualPaginationPreference({bool? val}) : super(val: val ?? _paginationModeDefaultValue); static const bool _paginationModeDefaultValue = false; @override ManualPaginationPreference copyWith({required bool? val}) { return ManualPaginationPreference(val: val); } @override String get key => 'paginationMode'; @override String get title => 'Manual Pagination'; @override String get subtitle => '''so you can get stuff done.'''; } /// Whether or not to use Custom Tabs for launching URLs. /// If false, default browser will be used. /// /// https://developer.chrome.com/docs/android/custom-tabs/ final class CustomTabPreference extends BooleanPreference { const CustomTabPreference({bool? val}) : super(val: val ?? _customTabModeDefaultValue); static const bool _customTabModeDefaultValue = false; @override CustomTabPreference copyWith({required bool? val}) { return CustomTabPreference(val: val); } @override String get key => 'customTabPreference'; @override String get title => 'Use Custom Tabs'; @override String get subtitle => '''use Custom tabs for URLs. If disabled, default browser is used instead.'''; @override bool get isDisplayable => Platform.isAndroid; } final class TrueDarkModePreference extends BooleanPreference { const TrueDarkModePreference({bool? val}) : super(val: val ?? _trueDarkModeDefaultValue); static const bool _trueDarkModeDefaultValue = false; @override TrueDarkModePreference copyWith({required bool? val}) { return TrueDarkModePreference(val: val); } @override String get key => 'trueDarkMode'; @override String get title => 'True Dark Mode'; @override String get subtitle => 'real dark.'; } final class HapticFeedbackPreference extends BooleanPreference { const HapticFeedbackPreference({bool? val}) : super(val: val ?? _hapticFeedbackModeDefaultValue); static const bool _hapticFeedbackModeDefaultValue = true; @override HapticFeedbackPreference copyWith({required bool? val}) { return HapticFeedbackPreference(val: val); } @override String get key => 'hapticFeedbackMode'; @override String get title => 'Haptic Feedback'; @override String get subtitle => ''; } final class FetchModePreference extends IntPreference { FetchModePreference({int? val}) : super(val: val ?? _fetchModeDefaultValue); static final int _fetchModeDefaultValue = FetchMode.eager.index; @override FetchModePreference copyWith({required int? val}) { return FetchModePreference(val: val); } @override String get key => 'fetchMode'; @override String get title => 'Default fetch mode'; } final class CommentsOrderPreference extends IntPreference { CommentsOrderPreference({int? val}) : super(val: val ?? _commentsOrderDefaultValue); static final int _commentsOrderDefaultValue = CommentsOrder.natural.index; @override CommentsOrderPreference copyWith({required int? val}) { return CommentsOrderPreference(val: val); } @override String get key => 'commentsOrder'; @override String get title => 'Default comments order'; } final class FontPreference extends IntPreference { FontPreference({int? val}) : super(val: val ?? _fontDefaultValue); static final int _fontDefaultValue = Font.robotoSlab.index; @override FontPreference copyWith({required int? val}) { return FontPreference(val: val); } @override String get key => 'font'; @override String get title => 'Default font'; } final class FontSizePreference extends IntPreference { FontSizePreference({int? val}) : super(val: val ?? _fontSizeDefaultValue); static final int _fontSizeDefaultValue = FontSize.regular.index; @override FontSizePreference copyWith({required int? val}) { return FontSizePreference(val: val); } @override String get key => 'fontSize'; @override String get title => 'Default font size'; } final class TabOrderPreference extends IntPreference { TabOrderPreference({int? val}) : super(val: val ?? _tabOrderDefaultValue); static final int _tabOrderDefaultValue = StoryType.convertToSettingsValue(StoryType.values); @override TabOrderPreference copyWith({required int? val}) { return TabOrderPreference(val: val); } @override String get key => 'tabOrder'; @override String get title => 'Tab order'; } final class StoryMarkingModePreference extends IntPreference { StoryMarkingModePreference({int? val}) : super(val: val ?? _markStoriesAsReadWhenPreferenceDefaultValue); static final int _markStoriesAsReadWhenPreferenceDefaultValue = StoryMarkingMode.tap.index; @override StoryMarkingModePreference copyWith({required int? val}) { return StoryMarkingModePreference(val: val); } @override String get key => 'storyMarkingMode'; @override String get title => 'Mark as Read on'; } final class AppColorPreference extends IntPreference { AppColorPreference({int? val}) : super(val: val ?? _appColorDefaultValue); static final int _appColorDefaultValue = materialColors.indexOf(Palette.deepOrange); @override AppColorPreference copyWith({required int? val}) { return AppColorPreference(val: val); } @override String get key => 'appColor'; @override String get title => 'Accent Color'; } final class TextScaleFactorPreference extends DoublePreference { const TextScaleFactorPreference({double? val}) : super(val: val ?? _textScaleFactorDefaultValue); static const double _textScaleFactorDefaultValue = 1; @override TextScaleFactorPreference copyWith({required double? val}) { return TextScaleFactorPreference(val: val); } @override String get key => 'appTextScaleFactor'; @override String get title => 'Default text scale factor'; } final class DateFormatPreference extends IntPreference { DateFormatPreference({int? val}) : super(val: val ?? _dateFormatDefaultValue); static final int _dateFormatDefaultValue = DateDisplayFormat.timeAgo.index; @override DateFormatPreference copyWith({required int? val}) { return DateFormatPreference(val: val); } @override String get key => 'dateFormat'; @override String get title => 'Date Format'; }