diff --git a/routes/_components/status/StatusMediaAttachments.html b/routes/_components/status/StatusMediaAttachments.html index 5466762..37d7b99 100644 --- a/routes/_components/status/StatusMediaAttachments.html +++ b/routes/_components/status/StatusMediaAttachments.html @@ -140,7 +140,9 @@ computed: { mediaAttachments: ({ originalStatus }) => originalStatus.media_attachments, sensitiveShown: ({ $sensitivesShown, uuid }) => !!$sensitivesShown[uuid], - sensitive: ({ originalStatus, $markMediaAsSensitive }) => originalStatus.sensitive || $markMediaAsSensitive, + sensitive: ({ originalStatus, $markMediaAsSensitive, $neverMarkMediaAsSensitive }) => ( + !$neverMarkMediaAsSensitive && ($markMediaAsSensitive || originalStatus.sensitive) + ), delegateKey: ({ uuid }) => `sensitive-${uuid}` }, methods: { diff --git a/routes/_pages/settings/general.html b/routes/_pages/settings/general.html index 9f6495f..0aad146 100644 --- a/routes/_pages/settings/general.html +++ b/routes/_pages/settings/general.html @@ -1,36 +1,45 @@

General Settings

-

UI Settings

+

Preferences

-
- - -
+ bind:checked="$markMediaAsSensitive" on:change="onChange(event)">
+
+ + +
+
+ + +
+
+ +

Accessibility

+
+
+ + +
+ bind:checked="$reduceMotion" on:change="onChange(event)">
+ bind:checked="$omitEmojiInDisplayNames" on:change="onChange(event)">
-
- - -
+ bind:checked="$disableLongAriaLabels" on:change="onChange(event)">
@@ -60,6 +69,21 @@ SettingsLayout, ThemeSettings }, + methods: { + onChange (event) { + // these two are mutually exclusive + let { markMediaAsSensitive, neverMarkMediaAsSensitive } = this.store.get() + if (markMediaAsSensitive && neverMarkMediaAsSensitive) { + if (event.target.id === 'choice-mark-media-sensitive') { + this.store.set({ neverMarkMediaAsSensitive: false }) + } else { + this.store.set({ markMediaAsSensitive: false }) + } + } + + this.store.save() + } + }, store: () => store, computed: { themeTitle: ({ $loggedInInstancesInOrder, $currentInstance }) => ( diff --git a/routes/_store/store.js b/routes/_store/store.js index f614c54..7cbb037 100644 --- a/routes/_store/store.js +++ b/routes/_store/store.js @@ -17,6 +17,7 @@ const persistedState = { loggedInInstances: {}, loggedInInstancesInOrder: [], markMediaAsSensitive: false, + neverMarkMediaAsSensitive: false, omitEmojiInDisplayNames: undefined, pinnedPages: {}, pushSubscription: null, diff --git a/tests/spec/023-mark-media-as-sensitive.js b/tests/spec/023-mark-media-as-sensitive.js new file mode 100644 index 0000000..368907f --- /dev/null +++ b/tests/spec/023-mark-media-as-sensitive.js @@ -0,0 +1,107 @@ +import { loginAsFoobar } from '../roles' +import { + generalSettingsButton, + getNthStatus, getNthStatusMedia, getNthStatusSensitiveMediaButton, homeNavButton, markMediaSensitiveInput, + scrollToStatus, settingsNavButton, neverMarkMediaSensitiveInput +} from '../utils' +import { indexWhere } from '../../routes/_utils/arrays' +import { homeTimeline } from '../fixtures' + +fixture`023-mark-media-as-sensitive.js` + .page`http://localhost:4002` + +async function checkSensitivityForStatus (t, idx, sensitive) { + if (sensitive) { + await t + .expect(getNthStatusSensitiveMediaButton(idx).exists).ok() + .expect(getNthStatusMedia(idx).exists).notOk() + } else { + await t + .expect(getNthStatusSensitiveMediaButton(idx).exists).notOk() + .expect(getNthStatusMedia(idx).exists).ok() + } +} + +async function checkSensitivity (t, shouldBeSensitive) { + let sensitiveKittenIdx = indexWhere(homeTimeline, _ => _.spoiler === 'kitten CW') + let sensitiveVideoIdx = indexWhere(homeTimeline, _ => _.content === 'secret video') + let videoIdx = indexWhere(homeTimeline, _ => _.content === "here's a video") + let sensitiveAnimatedKittenIdx = indexWhere(homeTimeline, _ => _.content === "here's a secret animated kitten gif") + let animatedKittenIdx = indexWhere(homeTimeline, _ => _.content === "here's an animated kitten gif") + + await t.hover(getNthStatus(0)) + + let expected = [ + [ sensitiveKittenIdx, shouldBeSensitive(true) ], + [ sensitiveVideoIdx, shouldBeSensitive(true) ], + [ videoIdx, shouldBeSensitive(false) ], + [ sensitiveAnimatedKittenIdx, shouldBeSensitive(true) ], + [ animatedKittenIdx, shouldBeSensitive(false) ] + ] + + for (let [ idx, sensitive ] of expected) { + await scrollToStatus(t, sensitiveKittenIdx) + await checkSensitivityForStatus(t, idx, sensitive) + } +} + +async function changeSetting (t, input, checked) { + await t + .click(settingsNavButton) + .click(generalSettingsButton) + .click(input) + if (checked) { + await t.expect(input.checked).ok() + } else { + await t.expect(input.checked).notOk() + } + await t.click(homeNavButton) +} + +async function doMarkMediaAsSensitive (t, checked) { + await changeSetting(t, markMediaSensitiveInput, checked) +} + +async function doNeverMarkMediaAsSensitive (t, checked) { + await changeSetting(t, neverMarkMediaSensitiveInput, checked) +} + +test('default sensitive settings', async t => { + await loginAsFoobar(t) + await checkSensitivity(t, sensitive => sensitive) +}) + +test('always mark media sensitive', async t => { + await loginAsFoobar(t) + await doMarkMediaAsSensitive(t, true) + await checkSensitivity(t, () => true) + // cleanup + await doMarkMediaAsSensitive(t, false) +}) + +test('never mark media sensitive', async t => { + await loginAsFoobar(t) + await doNeverMarkMediaAsSensitive(t, true) + await checkSensitivity(t, () => false) + // cleanup + await doNeverMarkMediaAsSensitive(t, false) +}) + +test('settings are mutually exclusive', async t => { + await loginAsFoobar(t) + await t + .click(settingsNavButton) + .click(generalSettingsButton) + .click(markMediaSensitiveInput) + .expect(markMediaSensitiveInput.checked).ok() + .expect(neverMarkMediaSensitiveInput.checked).notOk() + .click(neverMarkMediaSensitiveInput) + .expect(markMediaSensitiveInput.checked).notOk() + .expect(neverMarkMediaSensitiveInput.checked).ok() + .click(markMediaSensitiveInput) + .expect(markMediaSensitiveInput.checked).ok() + .expect(neverMarkMediaSensitiveInput.checked).notOk() + .click(markMediaSensitiveInput) + .expect(markMediaSensitiveInput.checked).notOk() + .expect(neverMarkMediaSensitiveInput.checked).notOk() +}) diff --git a/tests/utils.js b/tests/utils.js index ccb16e4..03a0d1e 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -42,6 +42,8 @@ export const followersButton = $('.account-profile-details > *:nth-child(3)') export const avatarInComposeBox = $('.compose-box-avatar') export const displayNameInComposeBox = $('.compose-box-display-name') export const generalSettingsButton = $('a[href="/settings/general"]') +export const markMediaSensitiveInput = $('#choice-mark-media-sensitive') +export const neverMarkMediaSensitiveInput = $('#choice-never-mark-media-sensitive') export const removeEmojiFromDisplayNamesInput = $('#choice-omit-emoji-in-display-names') export const favoritesCountElement = $('.status-favs').addCustomDOMProperties({ @@ -180,6 +182,14 @@ export function getNthStatusSpoiler (n) { return $(`${getNthStatusSelector(n)} .status-spoiler`) } +export function getNthStatusSensitiveMediaButton (n) { + return $(`${getNthStatusSelector(n)} .status-sensitive-media-button`) +} + +export function getNthStatusMedia (n) { + return $(`${getNthStatusSelector(n)} .status-media`) +} + export function getNthStatusHeader (n) { return $(`${getNthStatusSelector(n)} .status-header`) }