parent
8035cb2580
commit
35058ed965
|
@ -6,6 +6,7 @@ export function toggleContentWarningShown (realm) {
|
||||||
const newShown = !shown
|
const newShown = !shown
|
||||||
store.setComposeData(realm, {
|
store.setComposeData(realm, {
|
||||||
contentWarning: newShown ? contentWarning : '',
|
contentWarning: newShown ? contentWarning : '',
|
||||||
contentWarningShown: newShown
|
contentWarningShown: newShown,
|
||||||
|
sensitive: contentWarning && newShown // toggling content warning automatically toggles sensitive media
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
<ComposeToolbar {realm} {postPrivacy} {media} {contentWarningShown} {text} {poll} />
|
<ComposeToolbar {realm} {postPrivacy} {media} {contentWarningShown} {text} {poll} />
|
||||||
<ComposeLengthIndicator {length} {overLimit} />
|
<ComposeLengthIndicator {length} {overLimit} />
|
||||||
<ComposeMedia {realm} {media} />
|
<ComposeMedia {realm} {media} />
|
||||||
|
<ComposeMediaSensitive {realm} {media} {sensitive} {contentWarning} {contentWarningShown} />
|
||||||
</div>
|
</div>
|
||||||
</ComposeFileDrop>
|
</ComposeFileDrop>
|
||||||
<ComposeStickyButton {showSticky}
|
<ComposeStickyButton {showSticky}
|
||||||
|
@ -46,7 +47,8 @@
|
||||||
"avatar autosuggest autosuggest autosuggest"
|
"avatar autosuggest autosuggest autosuggest"
|
||||||
"avatar poll poll poll"
|
"avatar poll poll poll"
|
||||||
"avatar toolbar toolbar length"
|
"avatar toolbar toolbar length"
|
||||||
"avatar media media media";
|
"avatar media media media"
|
||||||
|
"avatar sensitive sensitive sensitive";
|
||||||
grid-template-columns: min-content minmax(0, max-content) 1fr 1fr;
|
grid-template-columns: min-content minmax(0, max-content) 1fr 1fr;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +97,7 @@
|
||||||
import ComposeFileDrop from './ComposeFileDrop.html'
|
import ComposeFileDrop from './ComposeFileDrop.html'
|
||||||
import ComposeAutosuggest from './ComposeAutosuggest.html'
|
import ComposeAutosuggest from './ComposeAutosuggest.html'
|
||||||
import ComposePoll from './ComposePoll.html'
|
import ComposePoll from './ComposePoll.html'
|
||||||
|
import ComposeMediaSensitive from './ComposeMediaSensitive.html'
|
||||||
import { measureText } from '../../_utils/measureText'
|
import { measureText } from '../../_utils/measureText'
|
||||||
import { POST_PRIVACY_OPTIONS } from '../../_static/statuses'
|
import { POST_PRIVACY_OPTIONS } from '../../_static/statuses'
|
||||||
import { store } from '../../_store/store'
|
import { store } from '../../_store/store'
|
||||||
|
@ -133,7 +136,8 @@
|
||||||
ComposeContentWarning,
|
ComposeContentWarning,
|
||||||
ComposeFileDrop,
|
ComposeFileDrop,
|
||||||
ComposeAutosuggest,
|
ComposeAutosuggest,
|
||||||
ComposePoll
|
ComposePoll,
|
||||||
|
ComposeMediaSensitive
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
size: undefined,
|
size: undefined,
|
||||||
|
@ -173,7 +177,8 @@
|
||||||
),
|
),
|
||||||
overLimit: ({ length, $maxStatusChars }) => length > $maxStatusChars,
|
overLimit: ({ length, $maxStatusChars }) => length > $maxStatusChars,
|
||||||
contentWarningShown: ({ composeData }) => composeData.contentWarningShown,
|
contentWarningShown: ({ composeData }) => composeData.contentWarningShown,
|
||||||
contentWarning: ({ composeData }) => composeData.contentWarning || ''
|
contentWarning: ({ composeData }) => composeData.contentWarning || '',
|
||||||
|
sensitive: ({ composeData }) => !!composeData.sensitive
|
||||||
},
|
},
|
||||||
transitions: {
|
transitions: {
|
||||||
slide
|
slide
|
||||||
|
@ -196,9 +201,9 @@
|
||||||
overLimit,
|
overLimit,
|
||||||
inReplyToUuid, // typical replies, using Pinafore-specific uuid
|
inReplyToUuid, // typical replies, using Pinafore-specific uuid
|
||||||
inReplyToId, // delete-and-redraft replies, using standard id
|
inReplyToId, // delete-and-redraft replies, using standard id
|
||||||
poll
|
poll,
|
||||||
|
sensitive
|
||||||
} = this.get()
|
} = this.get()
|
||||||
const sensitive = media.length && !!contentWarning
|
|
||||||
const mediaIds = media.map(_ => _.data.id)
|
const mediaIds = media.map(_ => _.data.id)
|
||||||
const mediaDescriptions = media.map(_ => _.description)
|
const mediaDescriptions = media.map(_ => _.description)
|
||||||
const mediaFocalPoints = media.map(_ => [_.focusX, _.focusY])
|
const mediaFocalPoints = media.map(_ => [_.focusX, _.focusY])
|
||||||
|
|
|
@ -41,7 +41,10 @@
|
||||||
const { realm } = this.get()
|
const { realm } = this.get()
|
||||||
this.observe('rawText', rawText => {
|
this.observe('rawText', rawText => {
|
||||||
updateContentWarningInStore(() => {
|
updateContentWarningInStore(() => {
|
||||||
this.store.setComposeData(realm, { contentWarning: rawText })
|
this.store.setComposeData(realm, {
|
||||||
|
sensitive: !!rawText, // toggling the content warning automatically toggles sensitive media
|
||||||
|
contentWarning: rawText
|
||||||
|
})
|
||||||
this.store.save()
|
this.store.save()
|
||||||
})
|
})
|
||||||
}, { init: false })
|
}, { init: false })
|
||||||
|
|
|
@ -113,6 +113,12 @@
|
||||||
max-height: 7vh;
|
max-height: 7vh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 320px) {
|
||||||
|
.compose-media-realm-dialog .compose-media-alt-input {
|
||||||
|
display: none; /* too small to show this - use the edit button instead */
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
import { store } from '../../_store/store'
|
import { store } from '../../_store/store'
|
||||||
|
|
79
src/routes/_components/compose/ComposeMediaSensitive.html
Normal file
79
src/routes/_components/compose/ComposeMediaSensitive.html
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{#if media.length}
|
||||||
|
<div class="compose-media-sensitive">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" bind:checked="rawChecked" {disabled} />
|
||||||
|
<span class="{disabled ? 'compose-sensitive-span-disabled' : ''}">
|
||||||
|
Mark media as sensitive
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
<style>
|
||||||
|
.compose-media-sensitive {
|
||||||
|
grid-area: sensitive;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.compose-sensitive-span-disabled {
|
||||||
|
color: var(--deemphasized-text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.compose-media-sensitive {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 320px) {
|
||||||
|
span {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { observe } from 'svelte-extras'
|
||||||
|
import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
oncreate () {
|
||||||
|
this.setupSyncToStore()
|
||||||
|
this.setupSyncFromStore()
|
||||||
|
},
|
||||||
|
data: () => ({
|
||||||
|
rawChecked: false
|
||||||
|
}),
|
||||||
|
computed: {
|
||||||
|
disabled: ({ contentWarning, contentWarningShown }) => contentWarning && contentWarningShown
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
observe,
|
||||||
|
setupSyncToStore () {
|
||||||
|
this.observe('rawChecked', () => {
|
||||||
|
scheduleIdleTask(() => {
|
||||||
|
const { realm } = this.get()
|
||||||
|
const { rawChecked } = this.get()
|
||||||
|
const sensitive = this.store.getComposeData(realm, 'sensitive')
|
||||||
|
if (sensitive !== rawChecked) {
|
||||||
|
this.store.setComposeData(realm, { sensitive: rawChecked })
|
||||||
|
this.store.save()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, { init: false })
|
||||||
|
},
|
||||||
|
setupSyncFromStore () {
|
||||||
|
this.observe('sensitive', sensitive => {
|
||||||
|
this.set({ rawChecked: sensitive })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -10,7 +10,8 @@ import {
|
||||||
homeNavButton,
|
homeNavButton,
|
||||||
mediaButton,
|
mediaButton,
|
||||||
notificationsNavButton,
|
notificationsNavButton,
|
||||||
uploadKittenImage
|
uploadKittenImage,
|
||||||
|
composeMediaSensitiveCheckbox, getNthStatusAndSensitiveImage, getNthStatusAndSensitiveButton, getNthStatusContent
|
||||||
} from '../utils'
|
} from '../utils'
|
||||||
import { loginAsFoobar } from '../roles'
|
import { loginAsFoobar } from '../roles'
|
||||||
|
|
||||||
|
@ -97,3 +98,20 @@ test('can post a status with empty content if there is media', async t => {
|
||||||
await t.click(composeButton)
|
await t.click(composeButton)
|
||||||
.expect(getNthStatusAndImage(1, 1).getAttribute('alt')).eql('just an image!')
|
.expect(getNthStatusAndImage(1, 1).getAttribute('alt')).eql('just an image!')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('can make an image sensitive without adding a CW', async t => {
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
await t
|
||||||
|
.typeText(composeInput, 'this is just a kitteh')
|
||||||
|
await (uploadKittenImage(2)())
|
||||||
|
await t
|
||||||
|
.typeText(getNthMediaAltInput(1), 'sensitive kitteh')
|
||||||
|
.expect(composeMediaSensitiveCheckbox.checked).notOk()
|
||||||
|
.click(composeMediaSensitiveCheckbox)
|
||||||
|
.expect(composeMediaSensitiveCheckbox.checked).ok()
|
||||||
|
.click(composeButton)
|
||||||
|
.expect(getNthStatusContent(1).innerText).contains('this is just a kitteh')
|
||||||
|
.expect(getNthStatusAndSensitiveImage(1, 1).getAttribute('src')).match(/^blob:http:\/\/localhost/)
|
||||||
|
.click(getNthStatusAndSensitiveButton(1, 1))
|
||||||
|
.expect(getNthStatusAndImage(1, 1).getAttribute('alt')).eql('sensitive kitteh')
|
||||||
|
})
|
||||||
|
|
|
@ -71,6 +71,8 @@ export const composePollExpiryOption = $('.compose-poll select option')
|
||||||
export const composePollExpiryInDialog = $('.modal-dialog .compose-poll select')
|
export const composePollExpiryInDialog = $('.modal-dialog .compose-poll select')
|
||||||
export const composePollAddButton = $('.compose-poll button:last-of-type')
|
export const composePollAddButton = $('.compose-poll button:last-of-type')
|
||||||
|
|
||||||
|
export const composeMediaSensitiveCheckbox = $('.compose-media-sensitive input')
|
||||||
|
|
||||||
export const postPrivacyDialogButtonUnlisted = $('[aria-label="Post privacy dialog"] li:nth-child(2) button')
|
export const postPrivacyDialogButtonUnlisted = $('[aria-label="Post privacy dialog"] li:nth-child(2) button')
|
||||||
|
|
||||||
export const accountProfileFilterStatuses = $('.account-profile-filters li:nth-child(1)')
|
export const accountProfileFilterStatuses = $('.account-profile-filters li:nth-child(1)')
|
||||||
|
@ -352,6 +354,14 @@ export function getNthStatusAndImage (nStatus, nImage) {
|
||||||
return $(`${getNthStatusSelector(nStatus)} .status-media .show-image-button:nth-child(${nImage}) img`)
|
return $(`${getNthStatusSelector(nStatus)} .status-media .show-image-button:nth-child(${nImage}) img`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNthStatusAndSensitiveButton (nStatus, nImage) {
|
||||||
|
return $(`${getNthStatusSelector(nStatus)} .status-sensitive-media-button:nth-child(${nImage})`)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNthStatusAndSensitiveImage (nStatus, nImage) {
|
||||||
|
return $(`${getNthStatusSelector(nStatus)} .status-media button:nth-child(${nImage}) img`)
|
||||||
|
}
|
||||||
|
|
||||||
export function getFirstVisibleStatus () {
|
export function getFirstVisibleStatus () {
|
||||||
return $('.list-item > article[aria-posinset]').nth(0)
|
return $('.list-item > article[aria-posinset]').nth(0)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue