pleroma-fe/src/components/post_status_form/post_status_form.vue

357 lines
9.4 KiB
Vue
Raw Normal View History

2016-10-30 16:53:58 +01:00
<template>
<div class="post-status-form">
2019-06-18 22:28:31 +02:00
<form @submit.prevent="postStatus(newStatus)" autocomplete="off">
<div class="form-group" >
<i18n
2019-04-02 17:19:45 +02:00
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private'"
path="post_status.account_not_locked_warning"
tag="p"
class="visibility-notice">
<router-link :to="{ name: 'user-settings' }">{{ $t('post_status.account_not_locked_warning_link') }}</router-link>
</i18n>
<p v-if="!hideScopeNotice && newStatus.visibility === 'public'" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.public') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.unlisted') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked" class="visibility-notice notice-dismissible">
<span>{{ $t('post_status.scope_notice.private') }}</span>
<a v-on:click.prevent="dismissScopeNotice()" class="button-icon dismiss">
<i class='icon-cancel'></i>
</a>
</p>
<p v-else-if="newStatus.visibility === 'direct'" class="visibility-notice">
2019-04-02 17:19:45 +02:00
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
</p>
2019-03-26 03:38:15 +01:00
<EmojiInput
v-if="newStatus.spoilerText || alwaysShowSubject"
:suggest="emojiSuggestor"
2018-06-07 11:03:50 +02:00
v-model="newStatus.spoilerText"
class="form-control"
>
<input
type="text"
:placeholder="$t('post_status.content_warning')"
v-model="newStatus.spoilerText"
class="form-post-subject"
/>
2019-06-18 20:30:35 +02:00
</EmojiInput>
<EmojiInput
:suggest="emojiUserSuggestor"
v-model="newStatus.status"
class="form-control main-input"
>
<textarea
ref="textarea"
v-model="newStatus.status"
:placeholder="$t('post_status.default')"
rows="1"
@keydown.meta.enter="postStatus(newStatus)"
@keyup.ctrl.enter="postStatus(newStatus)"
@drop="fileDrop"
@dragover.prevent="fileDrag"
@input="resize"
@paste="paste"
:disabled="posting"
class="form-post-body"
>
</textarea>
<p
v-if="hasStatusLengthLimit"
class="character-counter faint"
:class="{ error: isOverLengthLimit }"
>
{{ charactersLeft }}
</p>
2019-06-18 20:30:35 +02:00
</EmojiInput>
<div class="visibility-tray">
<div class="text-format" v-if="postFormats.length > 1">
<label for="post-content-type" class="select">
2019-02-21 17:16:11 +01:00
<select id="post-content-type" v-model="newStatus.contentType" class="form-control">
2019-03-07 05:13:04 +01:00
<option v-for="postFormat in postFormats" :key="postFormat" :value="postFormat">
{{$t(`post_status.content_type["${postFormat}"]`)}}
</option>
</select>
<i class="icon-down-open"></i>
</label>
</div>
<div class="text-format" v-if="postFormats.length === 1">
<span class="only-format">
{{$t(`post_status.content_type["${postFormats[0]}"]`)}}
</span>
</div>
<scope-selector
:showAll="showAllScopes"
:userDefault="userDefaultScope"
:originalScope="copyMessageScope"
:initialScope="newStatus.visibility"
:onScopeChange="changeVis"/>
2018-06-07 11:03:50 +02:00
</div>
</div>
2019-06-18 22:28:31 +02:00
<poll-form
ref="pollForm"
v-if="pollsAvailable"
:visible="pollFormVisible"
@update-poll="setPoll"
/>
<div class='form-bottom'>
<div class='form-bottom-left'>
<media-upload ref="mediaUpload" @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="uploadFailed" :drop-files="dropFiles"></media-upload>
2019-06-18 22:28:31 +02:00
<div v-if="pollsAvailable" class="poll-icon">
<i
:title="$t('polls.add_poll')"
@click="togglePollForm"
class="icon-chart-bar btn btn-default"
:class="pollFormVisible && 'selected'"
/>
2016-10-30 16:53:58 +01:00
</div>
</div>
2019-06-18 22:28:31 +02:00
<button v-if="posting" disabled class="btn btn-default">{{$t('post_status.posting')}}</button>
<button v-else-if="isOverLengthLimit" disabled class="btn btn-default">{{$t('general.submit')}}</button>
<button v-else :disabled="submitDisabled" type="submit" class="btn btn-default">{{$t('general.submit')}}</button>
</div>
<div class='alert error' v-if="error">
Error: {{ error }}
<i class="button-icon icon-cancel" @click="clearError"></i>
</div>
<div class="attachments">
<div class="media-upload-wrapper" v-for="file in newStatus.files">
<i class="fa button-icon icon-cancel" @click="removeMediaFile(file)"></i>
<div class="media-upload-container attachment">
<img class="thumbnail media-upload" :src="file.url" v-if="type(file) === 'image'"></img>
<video v-if="type(file) === 'video'" :src="file.url" controls></video>
<audio v-if="type(file) === 'audio'" :src="file.url" controls></audio>
<a v-if="type(file) === 'unknown'" :href="file.url">{{file.url}}</a>
</div>
</div>
2019-06-18 22:28:31 +02:00
</div>
<div class="upload_settings" v-if="newStatus.files.length > 0">
<input type="checkbox" id="filesSensitive" v-model="newStatus.nsfw">
<label for="filesSensitive">{{$t('post_status.attachments_sensitive')}}</label>
</div>
</form>
</div>
2016-10-30 16:53:58 +01:00
</template>
<script src="./post_status_form.js"></script>
<style lang="scss">
@import '../../_variables.scss';
.tribute-container {
2018-04-07 18:30:27 +02:00
ul {
padding: 0px;
li {
display: flex;
align-items: center;
}
}
img {
padding: 3px;
width: 16px;
height: 16px;
border-radius: $fallback--avatarAltRadius;
border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
}
}
.post-status-form {
.visibility-tray {
display: flex;
justify-content: space-between;
flex-direction: row-reverse;
padding-top: 5px;
}
}
2019-05-13 20:54:25 +02:00
.post-status-form {
2018-04-07 18:30:27 +02:00
.form-bottom {
display: flex;
padding: 0.5em;
height: 32px;
button {
width: 10em;
}
2018-04-07 18:30:27 +02:00
p {
margin: 0.35em;
padding: 0.35em;
display: flex;
}
}
2019-06-18 22:28:31 +02:00
.form-bottom-left {
display: flex;
flex: 1;
}
.text-format {
.only-format {
color: $fallback--faint;
color: var(--faint, $fallback--faint);
}
}
2019-06-18 22:28:31 +02:00
.poll-icon {
font-size: 26px;
flex: 1;
.selected {
color: $fallback--lightText;
color: var(--lightText, $fallback--lightText);
}
}
.icon-chart-bar {
cursor: pointer;
}
2018-04-07 18:30:27 +02:00
.error {
text-align: center;
}
.media-upload-wrapper {
flex: 0 0 auto;
max-width: 100%;
min-width: 50px;
margin-right: .2em;
margin-bottom: .5em;
.icon-cancel {
display: inline-block;
position: static;
margin: 0;
padding-bottom: 0;
margin-left: $fallback--attachmentRadius;
margin-left: var(--attachmentRadius, $fallback--attachmentRadius);
2018-10-07 18:59:22 +02:00
background-color: $fallback--fg;
2018-11-21 16:22:05 +01:00
background-color: var(--btn, $fallback--fg);
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
2018-04-07 18:30:27 +02:00
.attachments {
padding: 0 0.5em;
.attachment {
margin: 0;
2018-04-07 18:30:27 +02:00
position: relative;
flex: 0 0 auto;
border: 1px solid $fallback--border;
border: 1px solid var(--border, $fallback--border);
text-align: center;
audio {
min-width: 300px;
flex: 1 0 auto;
}
a {
display: block;
text-align: left;
line-height: 1.2;
padding: .5em;
}
2018-04-07 18:30:27 +02:00
}
i {
position: absolute;
margin: 10px;
padding: 5px;
background: rgba(230,230,230,0.6);
border-radius: $fallback--attachmentRadius;
border-radius: var(--attachmentRadius, $fallback--attachmentRadius);
font-weight: bold;
}
}
.btn {
cursor: pointer;
}
.btn[disabled] {
cursor: not-allowed;
}
form {
display: flex;
flex-direction: column;
padding: 0.6em;
}
.form-group {
display: flex;
flex-direction: column;
padding: 0.25em 0.5em 0.5em;
2018-04-07 18:30:27 +02:00
line-height:24px;
}
2018-06-07 11:03:50 +02:00
form textarea.form-cw {
line-height:16px;
resize: none;
overflow: hidden;
transition: min-height 200ms 100ms;
min-height: 1px;
}
.form-post-body {
height: 16px; // Only affects the empty-height
line-height: 16px;
2018-04-07 18:30:27 +02:00
resize: none;
overflow: hidden;
transition: min-height 200ms 100ms;
padding-bottom: 1.75em;
2018-04-07 18:30:27 +02:00
min-height: 1px;
box-sizing: content-box;
}
.form-post-body:focus {
2018-04-07 18:30:27 +02:00
min-height: 48px;
}
.main-input {
position: relative;
}
.character-counter {
position: absolute;
bottom: 0;
right: 0;
padding: 0;
margin: 0 0.5em;
&.error {
color: $fallback--cRed;
color: var(--cRed, $fallback--cRed);
}
}
2018-04-07 18:30:27 +02:00
.btn {
cursor: pointer;
}
.btn[disabled] {
cursor: not-allowed;
}
.icon-cancel {
cursor: pointer;
z-index: 4;
}
}
</style>