forked from cybrespace/pinafore
		
	start on content warnings
This commit is contained in:
		
							parent
							
								
									1de9e49f78
								
							
						
					
					
						commit
						2f5e19bd44
					
				
					 6 changed files with 82 additions and 12 deletions
				
			
		
							
								
								
									
										6
									
								
								routes/_actions/contentWarnings.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								routes/_actions/contentWarnings.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,6 @@
 | 
			
		|||
import { store } from '../_store/store'
 | 
			
		||||
 | 
			
		||||
export function toggleContentWarningShown (realm) {
 | 
			
		||||
  let shown = store.getComposeData(realm, 'contentWarningShown')
 | 
			
		||||
  store.setComposeData(realm, {contentWarningShown: !shown})
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,7 +12,7 @@
 | 
			
		|||
  }
 | 
			
		||||
  .compose-box-display-name {
 | 
			
		||||
    color: var(--deemphasized-text-color);
 | 
			
		||||
    grid-area: display-name;
 | 
			
		||||
    grid-area: name;
 | 
			
		||||
    min-width: 0;
 | 
			
		||||
    white-space: nowrap;
 | 
			
		||||
    overflow: hidden;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
<div class="compose-box {{overLimit ? 'over-char-limit' : ''}}">
 | 
			
		||||
  <ComposeAuthor />
 | 
			
		||||
  {{#if contentWarningShown}}
 | 
			
		||||
    <ComposeContentWarning :realm :contentWarning />
 | 
			
		||||
  {{/if}}
 | 
			
		||||
  <ComposeInput :realm :text />
 | 
			
		||||
  <ComposeLengthGauge :textLength :textOverLimit />
 | 
			
		||||
  <ComposeToolbar :realm :postPrivacy :media />
 | 
			
		||||
  <ComposeToolbar :realm :postPrivacy :media :contentWarningShown />
 | 
			
		||||
  <ComposeLengthIndicator :textLength :textOverLimit />
 | 
			
		||||
  <ComposeMedia :realm :media />
 | 
			
		||||
  <ComposeButton :textLength :textOverLimit />
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +17,8 @@
 | 
			
		|||
    display: grid;
 | 
			
		||||
    align-items: flex-start;
 | 
			
		||||
    grid-template-areas:
 | 
			
		||||
      "avatar display-name handle    handle"
 | 
			
		||||
      "avatar name       handle    handle"
 | 
			
		||||
      "avatar cw         cw        cw"
 | 
			
		||||
      "avatar input      input     input"
 | 
			
		||||
      "avatar gauge      gauge     gauge"
 | 
			
		||||
      "avatar toolbar    toolbar   length"
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +46,7 @@
 | 
			
		|||
  import ComposeInput from './ComposeInput.html'
 | 
			
		||||
  import ComposeButton from './ComposeButton.html'
 | 
			
		||||
  import ComposeMedia from './ComposeMedia.html'
 | 
			
		||||
  import ComposeContentWarning from './ComposeContentWarning.html'
 | 
			
		||||
  import { measureText } from '../../_utils/measureText'
 | 
			
		||||
  import { CHAR_LIMIT, POST_PRIVACY_OPTIONS } from '../../_static/statuses'
 | 
			
		||||
  import { store } from '../../_store/store'
 | 
			
		||||
| 
						 | 
				
			
			@ -54,7 +59,8 @@
 | 
			
		|||
      ComposeLengthIndicator,
 | 
			
		||||
      ComposeInput,
 | 
			
		||||
      ComposeButton,
 | 
			
		||||
      ComposeMedia
 | 
			
		||||
      ComposeMedia,
 | 
			
		||||
      ComposeContentWarning
 | 
			
		||||
    },
 | 
			
		||||
    store: () => store,
 | 
			
		||||
    computed: {
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +71,9 @@
 | 
			
		|||
      defaultPostPrivacyKey: ($currentVerifyCredentials) => $currentVerifyCredentials.source.privacy,
 | 
			
		||||
      postPrivacyKey: (composeData, defaultPostPrivacyKey) => composeData.postPrivacy || defaultPostPrivacyKey,
 | 
			
		||||
      textLength: (text) => measureText(text),
 | 
			
		||||
      textOverLimit: (textLength) => textLength > CHAR_LIMIT
 | 
			
		||||
      textOverLimit: (textLength) => textLength > CHAR_LIMIT,
 | 
			
		||||
      contentWarningShown: (composeData) => composeData.contentWarningShown,
 | 
			
		||||
      contentWarning: (composeData) => composeData.contentWarning || ''
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										49
									
								
								routes/_components/compose/ComposeContentWarning.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								routes/_components/compose/ComposeContentWarning.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
<input class="content-warning-input"
 | 
			
		||||
       type="text"
 | 
			
		||||
       placeholder="Content warning"
 | 
			
		||||
       aria-label="Content warning"
 | 
			
		||||
       bind:value=rawText
 | 
			
		||||
/>
 | 
			
		||||
<style>
 | 
			
		||||
  .content-warning-input {
 | 
			
		||||
    grid-area: cw;
 | 
			
		||||
    font-size: 1.2em;
 | 
			
		||||
    margin: 10px 0 0 5px;
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    border: 1px solid var(--input-border);
 | 
			
		||||
    width: calc(100% - 5px);
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
  import { store } from '../../_store/store'
 | 
			
		||||
  import debounce from 'lodash/debounce'
 | 
			
		||||
  import { scheduleIdleTask } from '../../_utils/scheduleIdleTask'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    oncreate() {
 | 
			
		||||
      this.setupSyncFromStore()
 | 
			
		||||
      this.setupSyncToStore()
 | 
			
		||||
    },
 | 
			
		||||
    store: () => store,
 | 
			
		||||
    data: () => ({
 | 
			
		||||
      rawText: ''
 | 
			
		||||
    }),
 | 
			
		||||
    methods: {
 | 
			
		||||
      setupSyncFromStore() {
 | 
			
		||||
        this.observe('contentWarning', contentWarning => {
 | 
			
		||||
          this.set({rawText: contentWarning})
 | 
			
		||||
        })
 | 
			
		||||
      },
 | 
			
		||||
      setupSyncToStore() {
 | 
			
		||||
        const saveText = debounce(() => scheduleIdleTask(() => this.store.save()), 1000)
 | 
			
		||||
 | 
			
		||||
        this.observe('rawText', rawText => {
 | 
			
		||||
          this.store.setComposeData(this.get('realm'), {
 | 
			
		||||
            contentWarning: rawText
 | 
			
		||||
          })
 | 
			
		||||
          saveText()
 | 
			
		||||
        }, {init: false})
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -17,8 +17,11 @@
 | 
			
		|||
    on:click="onPostPrivacyClick()"
 | 
			
		||||
  />
 | 
			
		||||
  <IconButton
 | 
			
		||||
    label="Add content warning"
 | 
			
		||||
    label="{{contentWarningShown ? 'Remove content warning' : 'Add content warning'}}"
 | 
			
		||||
    href="#fa-exclamation-triangle"
 | 
			
		||||
    on:click="onContentWarningClick()"
 | 
			
		||||
    pressable="true"
 | 
			
		||||
    pressed="{{contentWarningShown}}"
 | 
			
		||||
  />
 | 
			
		||||
  <input ref:input
 | 
			
		||||
         on:change="onFileChange(event)"
 | 
			
		||||
| 
						 | 
				
			
			@ -40,7 +43,7 @@
 | 
			
		|||
  import { updateCustomEmojiForInstance } from '../../_actions/emoji'
 | 
			
		||||
  import { importDialogs } from '../../_utils/asyncModules'
 | 
			
		||||
  import { doMediaUpload } from '../../_actions/media'
 | 
			
		||||
  import { POST_PRIVACY_OPTIONS } from '../../_static/statuses'
 | 
			
		||||
  import { toggleContentWarningShown } from '../../_actions/contentWarnings'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    oncreate() {
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +78,9 @@
 | 
			
		|||
      async onPostPrivacyClick() {
 | 
			
		||||
        let dialogs = await importDialogs()
 | 
			
		||||
        dialogs.showPostPrivacyDialog(this.get('realm'))
 | 
			
		||||
      },
 | 
			
		||||
      onContentWarningClick() {
 | 
			
		||||
        toggleContentWarningShown(this.get('realm'))
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,7 @@ test('inserts media', async t => {
 | 
			
		|||
test('removes media', async t => {
 | 
			
		||||
  await t.useRole(foobarRole)
 | 
			
		||||
  await (uploadKittenImage(1)())
 | 
			
		||||
  await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg')
 | 
			
		||||
  await (uploadKittenImage(2)())
 | 
			
		||||
  await t.expect(getNthMedia(1).getAttribute('alt')).eql('kitten1.jpg')
 | 
			
		||||
    .expect(getNthMedia(2).getAttribute('alt')).eql('kitten2.jpg')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue