From 1b781dd4f34a7cee9105eddbdb5ac2865e23f11a Mon Sep 17 00:00:00 2001 From: Roscoe Rubin-Rottenberg Date: Fri, 14 Aug 2026 17:17:07 -0400 Subject: [PATCH] refactor: remove self-label authoring --- .../templates/image_review_page_template.dart | 6 - .../templates/video_review_page_template.dart | 6 - lib/src/core/l10n/app_localizations.dart | 18 --- lib/src/core/l10n/app_localizations_en.dart | 10 -- lib/src/core/l10n/intl_en.arb | 12 -- .../models/content_warning_selection.dart | 28 ---- .../providers/video_upload_provider.dart | 16 -- .../posting/ui/pages/image_review_page.dart | 9 -- .../posting/ui/pages/story_post_page.dart | 13 -- .../posting/ui/pages/video_review_page.dart | 8 - .../ui/widgets/content_warning_selector.dart | 140 ------------------ .../posting/utils/story_direct_post.dart | 9 -- .../providers/video_upload_provider_test.dart | 16 -- .../content_warning_selector_test.dart | 74 --------- 14 files changed, 365 deletions(-) delete mode 100644 lib/src/features/posting/models/content_warning_selection.dart delete mode 100644 lib/src/features/posting/ui/widgets/content_warning_selector.dart delete mode 100644 test/src/features/posting/ui/widgets/content_warning_selector_test.dart diff --git a/lib/src/core/design_system/templates/image_review_page_template.dart b/lib/src/core/design_system/templates/image_review_page_template.dart index fd9a8bd..a5de199 100644 --- a/lib/src/core/design_system/templates/image_review_page_template.dart +++ b/lib/src/core/design_system/templates/image_review_page_template.dart @@ -46,7 +46,6 @@ class ImageReviewPageTemplate extends StatelessWidget { this.mentionController, this.onMentionsChanged, this.showCrossPostWarning = false, - this.contentWarningSection, this.backgroundColor, this.isOverLimit = false, }); @@ -71,7 +70,6 @@ class ImageReviewPageTemplate extends StatelessWidget { final bool crossPostValue; final ValueChanged onCrossPostChanged; final bool showCrossPostWarning; - final Widget? contentWarningSection; final String? selectedSoundTitle; final String? selectedSoundSubtitle; final VoidCallback? onAddSound; @@ -150,10 +148,6 @@ class ImageReviewPageTemplate extends StatelessWidget { onMentionsChanged: onMentionsChanged, maxChars: descriptionMaxChars, ), - if (contentWarningSection != null) ...[ - const SizedBox(height: 20), - contentWarningSection!, - ], const SizedBox(height: 20), _CrossPostSection( value: crossPostValue, diff --git a/lib/src/core/design_system/templates/video_review_page_template.dart b/lib/src/core/design_system/templates/video_review_page_template.dart index 153e50b..f66f3dd 100644 --- a/lib/src/core/design_system/templates/video_review_page_template.dart +++ b/lib/src/core/design_system/templates/video_review_page_template.dart @@ -37,7 +37,6 @@ class VideoReviewPageTemplate extends StatelessWidget { this.uploadIndeterminate = false, this.hasUploadError = false, this.onUploadRetry, - this.contentWarningSection, super.key, }); @@ -64,7 +63,6 @@ class VideoReviewPageTemplate extends StatelessWidget { final bool uploadIndeterminate; final bool hasUploadError; final VoidCallback? onUploadRetry; - final Widget? contentWarningSection; @override Widget build(BuildContext context) { @@ -118,10 +116,6 @@ class VideoReviewPageTemplate extends StatelessWidget { onMentionsChanged: onMentionsChanged, maxChars: descriptionMaxChars, ), - if (contentWarningSection != null) ...[ - const SizedBox(height: 20), - contentWarningSection!, - ], if (showCrossPost) ...[ const SizedBox(height: 20), _CrossPostSection( diff --git a/lib/src/core/l10n/app_localizations.dart b/lib/src/core/l10n/app_localizations.dart index 073cd88..cd68a7c 100644 --- a/lib/src/core/l10n/app_localizations.dart +++ b/lib/src/core/l10n/app_localizations.dart @@ -1736,24 +1736,6 @@ abstract class AppLocalizations { int count, ); - /// Heading for author-applied media content warnings - /// - /// In en, this message translates to: - /// **'Content warnings'** - String get labelContentWarnings; - - /// Explanation shown above author self-label controls - /// - /// In en, this message translates to: - /// **'Add any warnings that apply to the media you are posting.'** - String get messageContentWarningsDescription; - - /// Heading for mutually exclusive adult-content warnings - /// - /// In en, this message translates to: - /// **'Adult Content'** - String get labelAdultContent; - /// Heading over content concealed by moderation /// /// In en, this message translates to: diff --git a/lib/src/core/l10n/app_localizations_en.dart b/lib/src/core/l10n/app_localizations_en.dart index b1f969d..2971881 100644 --- a/lib/src/core/l10n/app_localizations_en.dart +++ b/lib/src/core/l10n/app_localizations_en.dart @@ -967,16 +967,6 @@ class AppLocalizationsEn extends AppLocalizations { return 'Followed by $firstName, $secondName, and $_temp0'; } - @override - String get labelContentWarnings => 'Content warnings'; - - @override - String get messageContentWarningsDescription => - 'Add any warnings that apply to the media you are posting.'; - - @override - String get labelAdultContent => 'Adult Content'; - @override String get moderationContentWarning => 'Content warning'; diff --git a/lib/src/core/l10n/intl_en.arb b/lib/src/core/l10n/intl_en.arb index 9aeff25..b33fbf6 100644 --- a/lib/src/core/l10n/intl_en.arb +++ b/lib/src/core/l10n/intl_en.arb @@ -1508,18 +1508,6 @@ } }, - "labelContentWarnings": "Content warnings", - "@labelContentWarnings": { - "description": "Heading for author-applied media content warnings" - }, - "messageContentWarningsDescription": "Add any warnings that apply to the media you are posting.", - "@messageContentWarningsDescription": { - "description": "Explanation shown above author self-label controls" - }, - "labelAdultContent": "Adult Content", - "@labelAdultContent": { - "description": "Heading for mutually exclusive adult-content warnings" - }, "moderationContentWarning": "Content warning", "@moderationContentWarning": { "description": "Heading over content concealed by moderation" diff --git a/lib/src/features/posting/models/content_warning_selection.dart b/lib/src/features/posting/models/content_warning_selection.dart deleted file mode 100644 index c9c1323..0000000 --- a/lib/src/features/posting/models/content_warning_selection.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:poptart_lex/com/atproto/label/defs.dart'; - -enum AdultContentWarning { sexual, nudity, porn } - -class ContentWarningSelection { - const ContentWarningSelection({this.adult, this.graphicMedia = false}); - - final AdultContentWarning? adult; - final bool graphicMedia; - - ContentWarningSelection copyWith({ - AdultContentWarning? adult, - bool clearAdult = false, - bool? graphicMedia, - }) { - return ContentWarningSelection( - adult: clearAdult ? null : adult ?? this.adult, - graphicMedia: graphicMedia ?? this.graphicMedia, - ); - } - - List get selfLabels => [ - if (adult case final value?) SelfLabel(val: value.name), - if (graphicMedia) const SelfLabel(val: 'graphic-media'), - ]; - - List get values => selfLabels.map((label) => label.val).toList(); -} diff --git a/lib/src/features/posting/providers/video_upload_provider.dart b/lib/src/features/posting/providers/video_upload_provider.dart index 9806663..8ece52d 100644 --- a/lib/src/features/posting/providers/video_upload_provider.dart +++ b/lib/src/features/posting/providers/video_upload_provider.dart @@ -1,7 +1,6 @@ import 'package:poptart/poptart.dart'; import 'package:bluesky_poptart/app/bsky/richtext/facet.dart'; import 'package:poptart_lex/com/atproto/repo/strong_ref.dart'; -import 'package:poptart_lex/com/atproto/label/defs.dart'; import 'package:get_it/get_it.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:spark/src/core/network/atproto/atproto.dart'; @@ -53,7 +52,6 @@ Future postVideo( bool crosspostToBsky = false, RepoStrongRef? soundRef, List facets = const [], - List selfLabelValues = const [], }) async { final logger = GetIt.I().getLogger('Posting Video'); try { @@ -66,9 +64,6 @@ Future postVideo( crosspostToBsky: crosspostToBsky, soundRef: soundRef, facets: facets, - selfLabels: selfLabelValues - .map((value) => SelfLabel(val: value)) - .toList(), ); } catch (error, stackTrace) { logger.e('Error posting video', error: error, stackTrace: stackTrace); @@ -86,7 +81,6 @@ Future postProcessedVideo({ RepoStrongRef? soundRef, List facets = const [], List storyEmbeds = const [], - List? selfLabels, }) async { final logger = GetIt.I().getLogger('Post Processed Video') ..d( @@ -123,7 +117,6 @@ Future postProcessedVideo({ Media.video(video: videoBlob, aspectRatio: aspectRatio), soundRef: effectiveSoundRef, embeds: storyEmbeds, - selfLabels: selfLabels, ); logger.i('Story posted: ${res.uri}'); return res; @@ -142,7 +135,6 @@ Future postProcessedVideo({ crosspostToBsky: crosspostToBsky, soundRef: effectiveSoundRef, facets: facets, - selfLabels: selfLabels, ); logger.i('Video flow complete (storyMode=false) success=${res != null}'); return res; @@ -169,7 +161,6 @@ Future processAndPostVideo( RepoStrongRef? soundRef, List facets = const [], List storyEmbeds = const [], - List selfLabelValues = const [], }) async { final logger = GetIt.I().getLogger('Process/Post Video') ..d( @@ -192,7 +183,6 @@ Future processAndPostVideo( soundRef: soundRef, facets: facets, storyEmbeds: storyEmbeds, - selfLabels: selfLabelValues.map((value) => SelfLabel(val: value)).toList(), ); } @@ -205,7 +195,6 @@ Future _postVideoRecord({ required bool crosspostToBsky, required RepoStrongRef? soundRef, required List facets, - required List? selfLabels, }) async { logger.d( 'Posting video (size=${blob.size}, crosspost=$crosspostToBsky, ' @@ -220,7 +209,6 @@ Future _postVideoRecord({ media: Media.video(video: blob, alt: altText, aspectRatio: aspectRatio), createdAt: DateTime.now().toUtc(), sound: soundRef, - selfLabels: selfLabels, ); final result = await GetIt.I().repo.createRecord( @@ -238,7 +226,6 @@ Future _postVideoRecord({ altText, result.uri.rkey, facets, - selfLabels, ); finalResult = await GetIt.I().repo.editRecordJson( uri: result.uri, @@ -260,7 +247,6 @@ Future _crosspostVideoToBlueSkyRecord( String altText, String rkey, List sparkFacets, - List? selfLabels, ) async { final logger = GetIt.I().getLogger('Crosspost Video') ..d('Crossposting video to Bluesky'); @@ -325,8 +311,6 @@ Future _crosspostVideoToBlueSkyRecord( 'alt': altText, }, 'createdAt': DateTime.now().toUtc().toIso8601String(), - if (selfLabels != null && selfLabels.isNotEmpty) - 'labels': SelfLabels(values: selfLabels).toJson(), }; final result = await sprkRepository.repo.createRecord( diff --git a/lib/src/features/posting/ui/pages/image_review_page.dart b/lib/src/features/posting/ui/pages/image_review_page.dart index e3676f0..c99d17b 100644 --- a/lib/src/features/posting/ui/pages/image_review_page.dart +++ b/lib/src/features/posting/ui/pages/image_review_page.dart @@ -15,10 +15,8 @@ import 'package:spark/src/core/ui/widgets/alt_text_editor_dialog.dart'; import 'package:spark/src/features/auth/providers/auth_providers.dart'; import 'package:spark/src/features/media_editor/canvas/ui/pages/post_image_editor_page.dart'; import 'package:spark/src/features/posting/models/mention_controller.dart'; -import 'package:spark/src/features/posting/models/content_warning_selection.dart'; import 'package:spark/src/features/posting/providers/post_story.dart'; import 'package:spark/src/features/posting/ui/widgets/image_sound_selection_sheet.dart'; -import 'package:spark/src/features/posting/ui/widgets/content_warning_selector.dart'; import 'package:spark/src/features/profile/providers/profile_feed_provider.dart'; import 'package:spark/src/features/sound/models/sound_audio_track.dart'; @@ -46,7 +44,6 @@ class _ImageReviewPageState extends ConsumerState { final Map _altTexts = {}; bool _crosspostToBsky = false; AudioTrack? _selectedSoundTrack; - ContentWarningSelection _contentWarnings = const ContentWarningSelection(); late final FeedRepository _feedRepository; Future showImageEditor(BuildContext context, XFile imageFile) async { @@ -150,7 +147,6 @@ class _ImageReviewPageState extends ConsumerState { final firstImage = uploadedImage.first; final storyProvider = postStoryProvider( Media.image(image: firstImage.image, alt: firstImage.alt), - selfLabels: _contentWarnings.selfLabels, ); final asyncResult = await ref.read(storyProvider.future); if (asyncResult == null) { @@ -166,7 +162,6 @@ class _ImageReviewPageState extends ConsumerState { crosspostToBsky: crosspostEnabled, facets: facets, soundRef: decodeSoundTrackStrongRef(_selectedSoundTrack?.id), - selfLabels: _contentWarnings.selfLabels, ); } return result; @@ -218,10 +213,6 @@ class _ImageReviewPageState extends ConsumerState { // Mentions are automatically tracked in the controller }, descriptionMaxChars: AppConstants.postDescriptionMaxChars, - contentWarningSection: ContentWarningSelector( - value: _contentWarnings, - onChanged: (value) => setState(() => _contentWarnings = value), - ), crossPostValue: _crosspostToBsky, onCrossPostChanged: (v) => setState(() => _crosspostToBsky = v), showCrossPostWarning: showCrossPostWarning, diff --git a/lib/src/features/posting/ui/pages/story_post_page.dart b/lib/src/features/posting/ui/pages/story_post_page.dart index 049aa1f..3c78d91 100644 --- a/lib/src/features/posting/ui/pages/story_post_page.dart +++ b/lib/src/features/posting/ui/pages/story_post_page.dart @@ -11,8 +11,6 @@ import 'package:spark/src/core/utils/error_messages.dart'; import 'package:spark/src/core/l10n/app_localizations.dart'; import 'package:spark/src/features/posting/providers/post_story.dart'; import 'package:spark/src/features/posting/providers/video_upload_provider.dart'; -import 'package:spark/src/features/posting/models/content_warning_selection.dart'; -import 'package:spark/src/features/posting/ui/widgets/content_warning_selector.dart'; /// Page that handles posting a story directly without a review UI. /// @@ -44,7 +42,6 @@ class _StoryPostPageState extends ConsumerState { bool _isPosting = false; String _statusMessage = 'Preparing...'; String? _error; - ContentWarningSelection _contentWarnings = const ContentWarningSelection(); @override void initState() { @@ -57,14 +54,6 @@ class _StoryPostPageState extends ConsumerState { Future _postStory() async { if (_isPosting) return; - final selection = await showContentWarningDialog(context); - if (!mounted) return; - if (selection == null) { - context.router.maybePop(false); - return; - } - _contentWarnings = selection; - setState(() { _isPosting = true; _error = null; @@ -115,7 +104,6 @@ class _StoryPostPageState extends ConsumerState { postStoryProvider( Media.image(image: uploadedImage.image, alt: uploadedImage.alt), embeds: widget.embeds, - selfLabels: _contentWarnings.selfLabels, ).future, ); @@ -135,7 +123,6 @@ class _StoryPostPageState extends ConsumerState { storyMode: true, soundRef: widget.soundRef, storyEmbeds: widget.embeds, - selfLabelValues: _contentWarnings.values, ).future, ); diff --git a/lib/src/features/posting/ui/pages/video_review_page.dart b/lib/src/features/posting/ui/pages/video_review_page.dart index b8e492f..274dc21 100644 --- a/lib/src/features/posting/ui/pages/video_review_page.dart +++ b/lib/src/features/posting/ui/pages/video_review_page.dart @@ -17,9 +17,7 @@ import 'package:spark/src/core/ui/widgets/alt_text_editor_dialog.dart'; import 'package:spark/src/core/utils/error_messages.dart'; import 'package:spark/src/features/auth/providers/auth_providers.dart'; import 'package:spark/src/features/posting/models/mention_controller.dart'; -import 'package:spark/src/features/posting/models/content_warning_selection.dart'; import 'package:spark/src/features/posting/providers/video_upload_provider.dart'; -import 'package:spark/src/features/posting/ui/widgets/content_warning_selector.dart'; import 'package:spark/src/features/profile/providers/profile_feed_provider.dart'; import 'package:video_player/video_player.dart'; @@ -52,7 +50,6 @@ class _VideoReviewPageState extends ConsumerState { bool _isPosting = false; String _videoAltText = ''; bool _crosspostToBsky = false; - ContentWarningSelection _contentWarnings = const ContentWarningSelection(); late XFile _video; late final FeedRepository _feedRepository; VideoPlayerController? _player; @@ -279,7 +276,6 @@ class _VideoReviewPageState extends ConsumerState { soundRef: widget.soundRef, crosspostToBsky: !widget.storyMode && _crosspostToBsky, facets: facets, - selfLabels: _contentWarnings.selfLabels, ); if (!mounted) return; @@ -382,10 +378,6 @@ class _VideoReviewPageState extends ConsumerState { // Mentions are automatically tracked in the controller }, descriptionMaxChars: AppConstants.postDescriptionMaxChars, - contentWarningSection: ContentWarningSelector( - value: _contentWarnings, - onChanged: (value) => setState(() => _contentWarnings = value), - ), showCrossPost: !widget.storyMode, crossPostValue: _crosspostToBsky, onCrossPostChanged: (v) => setState(() => _crosspostToBsky = v), diff --git a/lib/src/features/posting/ui/widgets/content_warning_selector.dart b/lib/src/features/posting/ui/widgets/content_warning_selector.dart deleted file mode 100644 index f6941e4..0000000 --- a/lib/src/features/posting/ui/widgets/content_warning_selector.dart +++ /dev/null @@ -1,140 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:spark/src/core/design_system/tokens/shapes.dart'; -import 'package:spark/src/core/design_system/tokens/typography.dart'; -import 'package:spark/src/core/l10n/app_localizations.dart'; -import 'package:spark/src/core/moderation/moderation.dart'; -import 'package:spark/src/features/posting/models/content_warning_selection.dart'; - -const _contentWarningValues = ['sexual', 'nudity', 'porn', 'graphic-media']; - -Future showContentWarningDialog( - BuildContext context, -) { - var selection = const ContentWarningSelection(); - return showDialog( - context: context, - builder: (context) => StatefulBuilder( - builder: (context, setDialogState) { - final l10n = AppLocalizations.of(context); - return AlertDialog( - title: Text(l10n.labelContentWarnings), - content: SingleChildScrollView( - child: ContentWarningSelector( - value: selection, - onChanged: (value) => setDialogState(() => selection = value), - ), - ), - actions: [ - TextButton( - onPressed: () => Navigator.pop(context), - child: Text(l10n.buttonCancel), - ), - FilledButton( - onPressed: () => Navigator.pop(context, selection), - child: Text(l10n.buttonPost), - ), - ], - ); - }, - ), - ); -} - -class ContentWarningSelector extends StatelessWidget { - const ContentWarningSelector({ - required this.value, - required this.onChanged, - super.key, - }); - - final ContentWarningSelection value; - final ValueChanged onChanged; - - @override - Widget build(BuildContext context) { - final l10n = AppLocalizations.of(context); - final colorScheme = Theme.of(context).colorScheme; - final strings = { - for (final value in _contentWarningValues) - value: builtInLabelDefinitionsByValue[value]!.localizedStrings(l10n)!, - }; - - return Semantics( - container: true, - label: l10n.labelContentWarnings, - child: Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - decoration: ShapeDecoration( - color: colorScheme.surfaceContainerHighest.withValues(alpha: 0.45), - shape: RoundedSuperellipseBorder( - borderRadius: BorderRadius.circular(AppShapes.squircleRadius), - side: BorderSide(color: colorScheme.outlineVariant), - ), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - l10n.labelContentWarnings, - style: AppTypography.textMediumBold.copyWith( - color: colorScheme.onSurface, - ), - ), - const SizedBox(height: 4), - Text( - l10n.messageContentWarningsDescription, - style: AppTypography.textSmallMedium.copyWith( - color: colorScheme.onSurfaceVariant, - ), - ), - const SizedBox(height: 12), - Text(l10n.labelAdultContent, style: AppTypography.textSmallBold), - const SizedBox(height: 8), - Wrap( - spacing: 8, - runSpacing: 8, - children: [ - for (final adult in AdultContentWarning.values) - ChoiceChip( - key: Key('content-warning-${adult.name}'), - label: Text(strings[adult.name]!.name), - selected: value.adult == adult, - onSelected: (selected) => onChanged( - value.copyWith(adult: adult, clearAdult: !selected), - ), - ), - ], - ), - if (value.adult case final adult?) ...[ - const SizedBox(height: 8), - Text( - strings[adult.name]!.description, - style: AppTypography.textSmallMedium.copyWith( - color: colorScheme.onSurfaceVariant, - ), - ), - ], - const SizedBox(height: 16), - FilterChip( - key: const Key('content-warning-graphic-media'), - label: Text(strings['graphic-media']!.name), - selected: value.graphicMedia, - onSelected: (selected) => - onChanged(value.copyWith(graphicMedia: selected)), - ), - if (value.graphicMedia) ...[ - const SizedBox(height: 8), - Text( - strings['graphic-media']!.description, - style: AppTypography.textSmallMedium.copyWith( - color: colorScheme.onSurfaceVariant, - ), - ), - ], - ], - ), - ), - ); - } -} diff --git a/lib/src/features/posting/utils/story_direct_post.dart b/lib/src/features/posting/utils/story_direct_post.dart index e9e27e5..56bf0f6 100644 --- a/lib/src/features/posting/utils/story_direct_post.dart +++ b/lib/src/features/posting/utils/story_direct_post.dart @@ -9,7 +9,6 @@ import 'package:spark/src/core/network/atproto/data/models/models.dart'; import 'package:spark/src/core/network/atproto/data/repositories/sprk_repository.dart'; import 'package:spark/src/features/posting/providers/post_story.dart'; import 'package:spark/src/features/posting/providers/video_upload_provider.dart'; -import 'package:spark/src/features/posting/ui/widgets/content_warning_selector.dart'; /// Utility for posting stories directly without a review page. class StoryDirectPost { @@ -25,9 +24,6 @@ class StoryDirectPost { XFile imageFile, { List embeds = const [], }) async { - final contentWarnings = await showContentWarningDialog(context); - if (contentWarnings == null || !context.mounted) return null; - // Show loading overlay final navigator = Navigator.of(context); @@ -59,7 +55,6 @@ class StoryDirectPost { postStoryProvider( Media.image(image: uploadedImage.image, alt: uploadedImage.alt), embeds: embeds, - selfLabels: contentWarnings.selfLabels, ).future, ); @@ -93,9 +88,6 @@ class StoryDirectPost { RepoStrongRef? soundRef, List embeds = const [], }) async { - final contentWarnings = await showContentWarningDialog(context); - if (contentWarnings == null || !context.mounted) return null; - // Show loading overlay final navigator = Navigator.of(context); @@ -115,7 +107,6 @@ class StoryDirectPost { storyMode: true, soundRef: soundRef, storyEmbeds: embeds, - selfLabelValues: contentWarnings.values, ).future, ); diff --git a/test/src/features/posting/providers/video_upload_provider_test.dart b/test/src/features/posting/providers/video_upload_provider_test.dart index 40d72cb..f0ba5c2 100644 --- a/test/src/features/posting/providers/video_upload_provider_test.dart +++ b/test/src/features/posting/providers/video_upload_provider_test.dart @@ -82,14 +82,12 @@ void main() { uploadResult: upload, storyMode: true, storyEmbeds: [embed], - selfLabels: const [SelfLabel(val: 'nudity')], ); expect(result, storyRepository.result); expect(soundRepository.createdBlobs, [upload.audioBlob]); expect(storyRepository.soundRef, createdSound); expect(storyRepository.embeds, [embed]); - expect(storyRepository.selfLabels, const [SelfLabel(val: 'nudity')]); expect(storyRepository.media, isA()); expect((storyRepository.media! as MediaVideo).video, upload.videoBlob); expect(repoRepository.createCalls, isEmpty); @@ -122,10 +120,6 @@ void main() { altText: 'a short clip', aspectRatio: const MediaAspectRatio(width: 9, height: 16), soundRef: sound, - selfLabels: const [ - SelfLabel(val: 'sexual'), - SelfLabel(val: 'graphic-media'), - ], ); expect(result, repoRepository.sparkResult); @@ -140,10 +134,6 @@ void main() { 'height': 16, }); expect(call.record['sound'], sound.toJson()); - expect(call.record['labels']['values'], [ - {r'$type': 'com.atproto.label.defs#selfLabel', 'val': 'sexual'}, - {r'$type': 'com.atproto.label.defs#selfLabel', 'val': 'graphic-media'}, - ]); expect(repoRepository.editCalls, isEmpty); }); @@ -156,7 +146,6 @@ void main() { uploadResult: upload, description: 'crosspost me', crosspostToBsky: true, - selfLabels: const [SelfLabel(val: 'porn')], ); expect(result, repoRepository.editedResult); @@ -165,9 +154,6 @@ void main() { 'app.bsky.feed.post', ]); expect(repoRepository.createCalls.last.rkey, 'spark-rkey'); - expect(repoRepository.createCalls.last.record['labels']['values'], [ - {r'$type': 'com.atproto.label.defs#selfLabel', 'val': 'porn'}, - ]); expect(repoRepository.editCalls, hasLength(1)); expect( repoRepository.editCalls.single.uri, @@ -247,7 +233,6 @@ class _FakeStoryRepository implements StoryRepository { Media? media; RepoStrongRef? soundRef; List? embeds; - List? selfLabels; @override Future postStory( @@ -260,7 +245,6 @@ class _FakeStoryRepository implements StoryRepository { this.media = media; this.soundRef = soundRef; this.embeds = embeds; - this.selfLabels = selfLabels; return result; } diff --git a/test/src/features/posting/ui/widgets/content_warning_selector_test.dart b/test/src/features/posting/ui/widgets/content_warning_selector_test.dart deleted file mode 100644 index e7dbe98..0000000 --- a/test/src/features/posting/ui/widgets/content_warning_selector_test.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:spark/src/core/l10n/app_localizations.dart'; -import 'package:spark/src/features/posting/models/content_warning_selection.dart'; -import 'package:spark/src/features/posting/ui/widgets/content_warning_selector.dart'; - -void main() { - testWidgets('adult warning is exclusive and graphic media is independent', ( - tester, - ) async { - final key = GlobalKey<_HostState>(); - await tester.pumpWidget(_app(_Host(key: key))); - await tester.pumpAndSettle(); - - await tester.tap(find.byKey(const Key('content-warning-sexual'))); - await tester.pump(); - await tester.tap(find.byKey(const Key('content-warning-graphic-media'))); - await tester.pump(); - - expect(key.currentState!.selection.values, ['sexual', 'graphic-media']); - - await tester.tap(find.byKey(const Key('content-warning-nudity'))); - await tester.pump(); - - expect(key.currentState!.selection.values, ['nudity', 'graphic-media']); - expect(find.text('For example, artistic nudes.'), findsOneWidget); - }); - - testWidgets('selected adult warning can be cleared', (tester) async { - final key = GlobalKey<_HostState>(); - await tester.pumpWidget(_app(_Host(key: key))); - await tester.pumpAndSettle(); - - final suggestive = find.byKey(const Key('content-warning-sexual')); - await tester.tap(suggestive); - await tester.pump(); - await tester.tap(suggestive); - await tester.pump(); - - expect(key.currentState!.selection.values, isEmpty); - }); -} - -Widget _app(Widget child) { - return ProviderScope( - child: MaterialApp( - localizationsDelegates: AppLocalizations.localizationsDelegates, - supportedLocales: AppLocalizations.supportedLocales, - home: Scaffold(body: child), - ), - ); -} - -class _Host extends StatefulWidget { - const _Host({super.key}); - - @override - State<_Host> createState() => _HostState(); -} - -class _HostState extends State<_Host> { - ContentWarningSelection selection = const ContentWarningSelection(); - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: ContentWarningSelector( - value: selection, - onChanged: (value) => setState(() => selection = value), - ), - ); - } -} -- 2.51.2