feat(ui): add option to always show sensitive media (#709)

fixes #699. I also went ahead and divided the settings into two groups: Preferences and Accessibility
This commit is contained in:
Nolan Lawson 2018-12-01 14:09:08 -08:00 committed by GitHub
parent f3254bb22d
commit ce61b821c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 160 additions and 16 deletions

View File

@ -140,7 +140,9 @@
computed: { computed: {
mediaAttachments: ({ originalStatus }) => originalStatus.media_attachments, mediaAttachments: ({ originalStatus }) => originalStatus.media_attachments,
sensitiveShown: ({ $sensitivesShown, uuid }) => !!$sensitivesShown[uuid], sensitiveShown: ({ $sensitivesShown, uuid }) => !!$sensitivesShown[uuid],
sensitive: ({ originalStatus, $markMediaAsSensitive }) => originalStatus.sensitive || $markMediaAsSensitive, sensitive: ({ originalStatus, $markMediaAsSensitive, $neverMarkMediaAsSensitive }) => (
!$neverMarkMediaAsSensitive && ($markMediaAsSensitive || originalStatus.sensitive)
),
delegateKey: ({ uuid }) => `sensitive-${uuid}` delegateKey: ({ uuid }) => `sensitive-${uuid}`
}, },
methods: { methods: {

View File

@ -1,36 +1,45 @@
<SettingsLayout page='settings/general' label="General"> <SettingsLayout page='settings/general' label="General">
<h1>General Settings</h1> <h1>General Settings</h1>
<h2>UI Settings</h2> <h2>Preferences</h2>
<form class="ui-settings" aria-label="UI settings"> <form class="ui-settings" aria-label="UI settings">
<div class="setting-group">
<input type="checkbox" id="choice-autoplay-gif"
bind:checked="$autoplayGifs" on:change="$save()">
<label for="choice-autoplay-gif">Autoplay GIFs</label>
</div>
<div class="setting-group"> <div class="setting-group">
<input type="checkbox" id="choice-mark-media-sensitive" <input type="checkbox" id="choice-mark-media-sensitive"
bind:checked="$markMediaAsSensitive" on:change="$save()"> bind:checked="$markMediaAsSensitive" on:change="onChange(event)">
<label for="choice-mark-media-sensitive">Always mark media as sensitive</label> <label for="choice-mark-media-sensitive">Always mark media as sensitive</label>
</div> </div>
<div class="setting-group">
<input type="checkbox" id="choice-never-mark-media-sensitive"
bind:checked="$neverMarkMediaAsSensitive" on:change="onChange(event)">
<label for="choice-never-mark-media-sensitive">Never mark media as sensitive</label>
</div>
<div class="setting-group">
<input type="checkbox" id="choice-disable-custom-scrollbars"
bind:checked="$disableCustomScrollbars" on:change="onChange(event)">
<label for="choice-disable-custom-scrollbars">Disable custom scrollbars</label>
</div>
</form>
<h2>Accessibility</h2>
<form class="ui-settings" aria-label="UI settings">
<div class="setting-group">
<input type="checkbox" id="choice-autoplay-gif"
bind:checked="$autoplayGifs" on:change="onChange(event)">
<label for="choice-autoplay-gif">Autoplay GIFs</label>
</div>
<div class="setting-group"> <div class="setting-group">
<input type="checkbox" id="choice-reduce-motion" <input type="checkbox" id="choice-reduce-motion"
bind:checked="$reduceMotion" on:change="$save()"> bind:checked="$reduceMotion" on:change="onChange(event)">
<label for="choice-reduce-motion">Reduce motion in UI animations</label> <label for="choice-reduce-motion">Reduce motion in UI animations</label>
</div> </div>
<div class="setting-group"> <div class="setting-group">
<input type="checkbox" id="choice-omit-emoji-in-display-names" <input type="checkbox" id="choice-omit-emoji-in-display-names"
bind:checked="$omitEmojiInDisplayNames" on:change="$save()"> bind:checked="$omitEmojiInDisplayNames" on:change="onChange(event)">
<label for="choice-omit-emoji-in-display-names">Remove emoji from user display names</label> <label for="choice-omit-emoji-in-display-names">Remove emoji from user display names</label>
</div> </div>
<div class="setting-group">
<input type="checkbox" id="choice-disable-custom-scrollbars"
bind:checked="$disableCustomScrollbars" on:change="$save()">
<label for="choice-disable-custom-scrollbars">Disable custom scrollbars</label>
</div>
<div class="setting-group"> <div class="setting-group">
<input type="checkbox" id="choice-disable-long-aria-labels" <input type="checkbox" id="choice-disable-long-aria-labels"
bind:checked="$disableLongAriaLabels" on:change="$save()"> bind:checked="$disableLongAriaLabels" on:change="onChange(event)">
<label for="choice-disable-long-aria-labels">Use short article ARIA labels</label> <label for="choice-disable-long-aria-labels">Use short article ARIA labels</label>
</div> </div>
</form> </form>
@ -60,6 +69,21 @@
SettingsLayout, SettingsLayout,
ThemeSettings 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, store: () => store,
computed: { computed: {
themeTitle: ({ $loggedInInstancesInOrder, $currentInstance }) => ( themeTitle: ({ $loggedInInstancesInOrder, $currentInstance }) => (

View File

@ -17,6 +17,7 @@ const persistedState = {
loggedInInstances: {}, loggedInInstances: {},
loggedInInstancesInOrder: [], loggedInInstancesInOrder: [],
markMediaAsSensitive: false, markMediaAsSensitive: false,
neverMarkMediaAsSensitive: false,
omitEmojiInDisplayNames: undefined, omitEmojiInDisplayNames: undefined,
pinnedPages: {}, pinnedPages: {},
pushSubscription: null, pushSubscription: null,

View File

@ -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()
})

View File

@ -42,6 +42,8 @@ export const followersButton = $('.account-profile-details > *:nth-child(3)')
export const avatarInComposeBox = $('.compose-box-avatar') export const avatarInComposeBox = $('.compose-box-avatar')
export const displayNameInComposeBox = $('.compose-box-display-name') export const displayNameInComposeBox = $('.compose-box-display-name')
export const generalSettingsButton = $('a[href="/settings/general"]') 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 removeEmojiFromDisplayNamesInput = $('#choice-omit-emoji-in-display-names')
export const favoritesCountElement = $('.status-favs').addCustomDOMProperties({ export const favoritesCountElement = $('.status-favs').addCustomDOMProperties({
@ -180,6 +182,14 @@ export function getNthStatusSpoiler (n) {
return $(`${getNthStatusSelector(n)} .status-spoiler`) 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) { export function getNthStatusHeader (n) {
return $(`${getNthStatusSelector(n)} .status-header`) return $(`${getNthStatusSelector(n)} .status-header`)
} }