mirror of
https://gitlab.com/mysocialportal/relatica
synced 2024-10-18 15:53:32 +00:00
Add ability to toggle off the spoiler alert/CW system app wide
Implements Feature Request #42
This commit is contained in:
parent
6504277005
commit
f8ac2a05c0
8 changed files with 53 additions and 9 deletions
|
@ -32,6 +32,8 @@
|
||||||
* Notifications are grouped by type, starting with mentions, within the unread and read groupings of the
|
* Notifications are grouped by type, starting with mentions, within the unread and read groupings of the
|
||||||
notification list. Defaults to on by default but can be toggled off in
|
notification list. Defaults to on by default but can be toggled off in
|
||||||
settings.([Feature #65](https://gitlab.com/mysocialportal/relatica/-/issues/65))
|
settings.([Feature #65](https://gitlab.com/mysocialportal/relatica/-/issues/65))
|
||||||
|
* Ability to turn off Spoiler Alert/CWs at the application
|
||||||
|
level. Defaults to on. ([Feature #42](https://gitlab.com/mysocialportal/relatica/-/issues/42))
|
||||||
|
|
||||||
## Version 0.10.1 (beta)
|
## Version 0.10.1 (beta)
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../globals.dart';
|
||||||
import '../models/timeline_entry.dart';
|
import '../models/timeline_entry.dart';
|
||||||
import '../services/auth_service.dart';
|
import '../services/auth_service.dart';
|
||||||
|
import '../services/setting_service.dart';
|
||||||
import '../utils/clipboard_utils.dart';
|
import '../utils/clipboard_utils.dart';
|
||||||
import '../utils/url_opening_utils.dart';
|
import '../utils/url_opening_utils.dart';
|
||||||
import 'html_text_viewer_control.dart';
|
import 'html_text_viewer_control.dart';
|
||||||
|
@ -27,6 +29,7 @@ class SearchResultStatusControl extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SearchResultStatusControlState extends State<SearchResultStatusControl> {
|
class _SearchResultStatusControlState extends State<SearchResultStatusControl> {
|
||||||
|
var showSpoilerControl = true;
|
||||||
var showContent = false;
|
var showContent = false;
|
||||||
|
|
||||||
TimelineEntry get status => widget.status;
|
TimelineEntry get status => widget.status;
|
||||||
|
@ -34,7 +37,9 @@ class _SearchResultStatusControlState extends State<SearchResultStatusControl> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
showContent = widget.status.spoilerText.isEmpty;
|
showSpoilerControl = getIt<SettingsService>().spoilerHidingEnabled;
|
||||||
|
showContent =
|
||||||
|
!showSpoilerControl ? true : widget.status.spoilerText.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -77,7 +82,7 @@ class _SearchResultStatusControlState extends State<SearchResultStatusControl> {
|
||||||
const VerticalPadding(
|
const VerticalPadding(
|
||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
if (status.spoilerText.isNotEmpty)
|
if (showSpoilerControl && status.spoilerText.isNotEmpty)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
@ -85,7 +90,7 @@ class _SearchResultStatusControlState extends State<SearchResultStatusControl> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
'Content Summary: ${status.spoilerText} (Click to ${showContent ? "Hide" : "Show"}}')),
|
'Content Summary: ${status.spoilerText} (Click to ${showContent ? "Hide" : "Show"})')),
|
||||||
if (showContent) ...[
|
if (showContent) ...[
|
||||||
buildBody(context),
|
buildBody(context),
|
||||||
const VerticalPadding(
|
const VerticalPadding(
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:relatica/utils/snackbar_builder.dart';
|
|
||||||
import 'package:result_monad/result_monad.dart';
|
import 'package:result_monad/result_monad.dart';
|
||||||
|
|
||||||
import '../../globals.dart';
|
import '../../globals.dart';
|
||||||
|
@ -13,6 +12,7 @@ import '../../models/filters/timeline_entry_filter.dart';
|
||||||
import '../../models/flattened_tree_item.dart';
|
import '../../models/flattened_tree_item.dart';
|
||||||
import '../../models/timeline_entry.dart';
|
import '../../models/timeline_entry.dart';
|
||||||
import '../../services/auth_service.dart';
|
import '../../services/auth_service.dart';
|
||||||
|
import '../../services/setting_service.dart';
|
||||||
import '../../services/timeline_entry_filter_service.dart';
|
import '../../services/timeline_entry_filter_service.dart';
|
||||||
import '../../services/timeline_manager.dart';
|
import '../../services/timeline_manager.dart';
|
||||||
import '../../utils/active_profile_selector.dart';
|
import '../../utils/active_profile_selector.dart';
|
||||||
|
@ -20,6 +20,7 @@ import '../../utils/clipboard_utils.dart';
|
||||||
import '../../utils/filter_runner.dart';
|
import '../../utils/filter_runner.dart';
|
||||||
import '../../utils/html_to_edit_text_helper.dart';
|
import '../../utils/html_to_edit_text_helper.dart';
|
||||||
import '../../utils/responsive_sizes_calculator.dart';
|
import '../../utils/responsive_sizes_calculator.dart';
|
||||||
|
import '../../utils/snackbar_builder.dart';
|
||||||
import '../../utils/url_opening_utils.dart';
|
import '../../utils/url_opening_utils.dart';
|
||||||
import '../html_text_viewer_control.dart';
|
import '../html_text_viewer_control.dart';
|
||||||
import '../media_attachment_viewer_control.dart';
|
import '../media_attachment_viewer_control.dart';
|
||||||
|
@ -49,6 +50,7 @@ class FlattenedTreeEntryControl extends StatefulWidget {
|
||||||
class _StatusControlState extends State<FlattenedTreeEntryControl> {
|
class _StatusControlState extends State<FlattenedTreeEntryControl> {
|
||||||
static final _logger = Logger('$FlattenedTreeEntryControl');
|
static final _logger = Logger('$FlattenedTreeEntryControl');
|
||||||
|
|
||||||
|
var showSpoilerControl = true;
|
||||||
var showContent = true;
|
var showContent = true;
|
||||||
var showFilteredPost = false;
|
var showFilteredPost = false;
|
||||||
var showComments = false;
|
var showComments = false;
|
||||||
|
@ -67,7 +69,8 @@ class _StatusControlState extends State<FlattenedTreeEntryControl> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
showContent = entry.spoilerText.isEmpty;
|
showSpoilerControl = getIt<SettingsService>().spoilerHidingEnabled;
|
||||||
|
showContent = !showSpoilerControl ? true : entry.spoilerText.isEmpty;
|
||||||
showComments = isPost ? false : true;
|
showComments = isPost ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +167,7 @@ class _StatusControlState extends State<FlattenedTreeEntryControl> {
|
||||||
const VerticalPadding(
|
const VerticalPadding(
|
||||||
height: 5,
|
height: 5,
|
||||||
),
|
),
|
||||||
if (entry.spoilerText.isNotEmpty)
|
if (showSpoilerControl && entry.spoilerText.isNotEmpty)
|
||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
|
@ -38,8 +38,6 @@ class _PostControlState extends State<PostControl> {
|
||||||
final ItemPositionsListener itemPositionsListener =
|
final ItemPositionsListener itemPositionsListener =
|
||||||
ItemPositionsListener.create();
|
ItemPositionsListener.create();
|
||||||
|
|
||||||
var showContent = true;
|
|
||||||
|
|
||||||
EntryTreeItem get item => widget.originalItem;
|
EntryTreeItem get item => widget.originalItem;
|
||||||
|
|
||||||
TimelineEntry get entry => item.entry;
|
TimelineEntry get entry => item.entry;
|
||||||
|
@ -47,7 +45,6 @@ class _PostControlState extends State<PostControl> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
showContent = entry.spoilerText.isEmpty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -7,6 +7,7 @@ import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||||
|
|
||||||
import '../../models/TimelineIdentifiers.dart';
|
import '../../models/TimelineIdentifiers.dart';
|
||||||
import '../../services/network_status_service.dart';
|
import '../../services/network_status_service.dart';
|
||||||
|
import '../../services/setting_service.dart';
|
||||||
import '../../services/timeline_manager.dart';
|
import '../../services/timeline_manager.dart';
|
||||||
import '../../utils/active_profile_selector.dart';
|
import '../../utils/active_profile_selector.dart';
|
||||||
import 'post_control.dart';
|
import 'post_control.dart';
|
||||||
|
@ -36,6 +37,7 @@ class TimelinePanel extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_logger.finer('Build');
|
_logger.finer('Build');
|
||||||
|
context.watch<SettingsService>().spoilerHidingEnabled;
|
||||||
final nss = getIt<NetworkStatusService>();
|
final nss = getIt<NetworkStatusService>();
|
||||||
final manager = context
|
final manager = context
|
||||||
.watch<ActiveProfileSelector<TimelineManager>>()
|
.watch<ActiveProfileSelector<TimelineManager>>()
|
||||||
|
|
|
@ -76,6 +76,16 @@ class OAuthCredentials implements ICredentials {
|
||||||
'id': id,
|
'id': id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) =>
|
||||||
|
identical(this, other) ||
|
||||||
|
other is OAuthCredentials &&
|
||||||
|
runtimeType == other.runtimeType &&
|
||||||
|
id == other.id;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => id.hashCode;
|
||||||
|
|
||||||
static OAuthCredentials fromJson(Map<String, dynamic> json) =>
|
static OAuthCredentials fromJson(Map<String, dynamic> json) =>
|
||||||
OAuthCredentials(
|
OAuthCredentials(
|
||||||
clientId: json['clientId'],
|
clientId: json['clientId'],
|
||||||
|
|
|
@ -32,6 +32,7 @@ class SettingsScreen extends StatelessWidget {
|
||||||
buildVersionString(),
|
buildVersionString(),
|
||||||
buildLowBandwidthWidget(settings),
|
buildLowBandwidthWidget(settings),
|
||||||
buildNotificationGroupingWidget(settings),
|
buildNotificationGroupingWidget(settings),
|
||||||
|
buildSpoilerHidingEnabledWidget(settings),
|
||||||
buildThemeWidget(settings),
|
buildThemeWidget(settings),
|
||||||
if (!kReleaseMode) buildColorBlindnessTestSettings(settings),
|
if (!kReleaseMode) buildColorBlindnessTestSettings(settings),
|
||||||
buildClearCaches(context),
|
buildClearCaches(context),
|
||||||
|
@ -80,6 +81,18 @@ class SettingsScreen extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildSpoilerHidingEnabledWidget(SettingsService settings) {
|
||||||
|
return ListTile(
|
||||||
|
title: const Text('Spoiler/Content Warning Hiding'),
|
||||||
|
trailing: Switch(
|
||||||
|
onChanged: (value) {
|
||||||
|
settings.spoilerHidingEnabled = value;
|
||||||
|
},
|
||||||
|
value: settings.spoilerHidingEnabled,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildThemeWidget(SettingsService settings) {
|
Widget buildThemeWidget(SettingsService settings) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: const Text('Dark Mode Theme:'),
|
title: const Text('Dark Mode Theme:'),
|
||||||
|
|
|
@ -34,6 +34,16 @@ class SettingsService extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _spoilerHidingEnabled = true;
|
||||||
|
|
||||||
|
bool get spoilerHidingEnabled => _spoilerHidingEnabled;
|
||||||
|
|
||||||
|
set spoilerHidingEnabled(bool value) {
|
||||||
|
_spoilerHidingEnabled = value;
|
||||||
|
_prefs.setBool(_spoilerHidingEnabledKey, _spoilerHidingEnabled);
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
var _themeMode = ThemeMode.system;
|
var _themeMode = ThemeMode.system;
|
||||||
|
|
||||||
ThemeMode get themeMode => _themeMode;
|
ThemeMode get themeMode => _themeMode;
|
||||||
|
@ -83,6 +93,7 @@ class SettingsService extends ChangeNotifier {
|
||||||
_prefs = await SharedPreferences.getInstance();
|
_prefs = await SharedPreferences.getInstance();
|
||||||
_lowBandwidthMode = _prefs.getBool(_lowBandwidthModeKey) ?? false;
|
_lowBandwidthMode = _prefs.getBool(_lowBandwidthModeKey) ?? false;
|
||||||
_notificationGrouping = _prefs.getBool(_notificationGroupingKey) ?? true;
|
_notificationGrouping = _prefs.getBool(_notificationGroupingKey) ?? true;
|
||||||
|
_spoilerHidingEnabled = _prefs.getBool(_spoilerHidingEnabledKey) ?? true;
|
||||||
_themeMode = ThemeModeExtensions.parse(_prefs.getString(_themeModeKey));
|
_themeMode = ThemeModeExtensions.parse(_prefs.getString(_themeModeKey));
|
||||||
_colorBlindnessType = _colorBlindnessTypeFromPrefs(_prefs);
|
_colorBlindnessType = _colorBlindnessTypeFromPrefs(_prefs);
|
||||||
_logLevel = _levelFromPrefs(_prefs);
|
_logLevel = _levelFromPrefs(_prefs);
|
||||||
|
@ -97,6 +108,7 @@ const _colorBlindnessTestingModeKey = 'ColorBlindnessTestingMode';
|
||||||
const _logLevelKey = 'LogLevel';
|
const _logLevelKey = 'LogLevel';
|
||||||
const _networkCapabilitiesKey = 'NetworkCapabilities';
|
const _networkCapabilitiesKey = 'NetworkCapabilities';
|
||||||
const _notificationGroupingKey = 'NotificationGrouping';
|
const _notificationGroupingKey = 'NotificationGrouping';
|
||||||
|
const _spoilerHidingEnabledKey = 'SpoilerHidingEnabled';
|
||||||
|
|
||||||
ColorBlindnessType _colorBlindnessTypeFromPrefs(SharedPreferences prefs) {
|
ColorBlindnessType _colorBlindnessTypeFromPrefs(SharedPreferences prefs) {
|
||||||
final cbString = prefs.getString(_colorBlindnessTestingModeKey);
|
final cbString = prefs.getString(_colorBlindnessTestingModeKey);
|
||||||
|
|
Loading…
Reference in a new issue