Merge branch 'polish' into shigusegubu

* polish:
  added option for logo in navbar to follow color scheme of the rest of the site also fixed potential mess-up between api/static configs
  i18n: make "plain text" translatable
  add the ability to select a post's content type
This commit is contained in:
Henry Jameson 2018-08-31 04:21:46 +03:00
commit c2a4ae3654
10 changed files with 115 additions and 28 deletions

View file

@ -18,7 +18,14 @@ export default {
ChatPanel ChatPanel
}, },
data: () => ({ data: () => ({
mobileActivePanel: 'timeline' mobileActivePanel: 'timeline',
supportsMask: window.CSS && window.CSS.supports && (
window.CSS.supports('mask-size', 'contain') ||
window.CSS.supports('-webkit-mask-size', 'contain') ||
window.CSS.supports('-moz-mask-size', 'contain') ||
window.CSS.supports('-ms-mask-size', 'contain') ||
window.CSS.supports('-o-mask-size', 'contain')
)
}), }),
created () { created () {
// Load the locale from the storage // Load the locale from the storage
@ -29,7 +36,27 @@ export default {
background () { background () {
return this.currentUser.background_image || this.$store.state.config.background return this.currentUser.background_image || this.$store.state.config.background
}, },
logoStyle () { return { 'background-image': `url(${this.$store.state.config.logo})` } }, enableMask () { return this.supportsMask && this.$store.state.config.logoMask },
logoStyle () {
return {
'visibility': this.enableMask ? 'hidden' : 'visible'
}
},
logoMaskStyle () {
return this.enableMask ? {
'mask-image': `url(${this.$store.state.config.logo})`
} : {
'background-color': this.enableMask ? '' : 'transparent'
}
},
logoBgStyle () {
return Object.assign({
'margin': `${this.$store.state.config.logoMargin} 0`
}, this.enableMask ? {} : {
'background-color': this.enableMask ? '' : 'transparent'
})
},
logo () { return this.$store.state.config.logo },
style () { return { 'background-image': `url(${this.background})` } }, style () { return { 'background-image': `url(${this.background})` } },
sitename () { return this.$store.state.config.name }, sitename () { return this.$store.state.config.name },
chat () { return this.$store.state.chat.channel.state === 'joined' }, chat () { return this.$store.state.chat.channel.state === 'joined' },

View file

@ -236,6 +236,36 @@ nav {
position: fixed; position: fixed;
height: 50px; height: 50px;
.logo {
display: flex;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
align-items: stretch;
justify-content: center;
flex: 0 0 auto;
z-index: -1;
.mask {
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
background-color: $fallback--fg;
background-color: var(--fg, $fallback--fg);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
img {
display: block;
flex: 0;
}
}
.inner-nav { .inner-nav {
padding-left: 20px; padding-left: 20px;
padding-right: 20px; padding-right: 20px;
@ -244,9 +274,6 @@ nav {
flex-basis: 970px; flex-basis: 970px;
margin: auto; margin: auto;
height: 50px; height: 50px;
background-repeat: no-repeat;
background-position: center;
background-size: auto 80%;
a i { a i {
color: $fallback--link; color: $fallback--link;
@ -471,6 +498,10 @@ nav {
color: $fallback--lightFg; color: $fallback--lightFg;
color: var(--lightFg, $fallback--lightFg); color: var(--lightFg, $fallback--lightFg);
} }
.text-format {
float: right;
}
} }
.visibility-notice { .visibility-notice {

View file

@ -1,7 +1,11 @@
<template> <template>
<div id="app" v-bind:style="style"> <div id="app" v-bind:style="style">
<nav class='container' @click="scrollToTop()" id="nav"> <nav class='container' @click="scrollToTop()" id="nav">
<div class='inner-nav' :style="logoStyle"> <div class='logo' :style='logoBgStyle'>
<div class='mask' :style='logoMaskStyle'></div>
<img :src='logo' :style='logoStyle'>
</div>
<div class='inner-nav'>
<div class='item'> <div class='item'>
<router-link :to="{ name: 'root'}">{{sitename}}</router-link> <router-link :to="{ name: 'root'}">{{sitename}}</router-link>
</div> </div>

View file

@ -55,6 +55,7 @@ const PostStatusForm = {
newStatus: { newStatus: {
spoilerText: this.subject, spoilerText: this.subject,
status: statusText, status: statusText,
contentType: 'text/plain',
nsfw: false, nsfw: false,
files: [], files: [],
visibility: this.messageScope || this.$store.state.users.currentUser.default_scope visibility: this.messageScope || this.$store.state.users.currentUser.default_scope
@ -210,13 +211,15 @@ const PostStatusForm = {
sensitive: newStatus.nsfw, sensitive: newStatus.nsfw,
media: newStatus.files, media: newStatus.files,
store: this.$store, store: this.$store,
inReplyToStatusId: this.replyTo inReplyToStatusId: this.replyTo,
contentType: newStatus.contentType
}).then((data) => { }).then((data) => {
if (!data.error) { if (!data.error) {
this.newStatus = { this.newStatus = {
status: '', status: '',
files: [], files: [],
visibility: newStatus.visibility visibility: newStatus.visibility,
contentType: newStatus.contentType
} }
this.$emit('posted') this.$emit('posted')
let el = this.$el.querySelector('textarea') let el = this.$el.querySelector('textarea')

View file

@ -32,11 +32,21 @@
@input="resize" @input="resize"
@paste="paste"> @paste="paste">
</textarea> </textarea>
<div v-if="scopeOptionsEnabled" class="visibility-tray"> <div class="visibility-tray">
<i v-on:click="changeVis('direct')" class="icon-mail-alt" :class="vis.direct" :title="$t('post_status.scope.direct')"></i> <span class="text-format">
<i v-on:click="changeVis('private')" class="icon-lock" :class="vis.private" :title="$t('post_status.scope.private')"></i> <select v-model="newStatus.contentType" class="form-control">
<i v-on:click="changeVis('unlisted')" class="icon-lock-open-alt" :class="vis.unlisted" :title="$t('post_status.scope.unlisted')"></i> <option value="text/plain">{{$t('post_status.content_type.plain_text')}}</option>
<i v-on:click="changeVis('public')" class="icon-globe" :class="vis.public" :title="$t('post_status.scope.public')"></i> <option value="text/html">HTML</option>
<option value="text/markdown">Markdown</option>
</select>
</span>
<div v-if="scopeOptionsEnabled">
<i v-on:click="changeVis('direct')" class="icon-mail-alt" :class="vis.direct" :title="$t('post_status.scope.direct')"></i>
<i v-on:click="changeVis('private')" class="icon-lock" :class="vis.private" :title="$t('post_status.scope.private')"></i>
<i v-on:click="changeVis('unlisted')" class="icon-lock-open-alt" :class="vis.unlisted" :title="$t('post_status.scope.unlisted')"></i>
<i v-on:click="changeVis('public')" class="icon-globe" :class="vis.public" :title="$t('post_status.scope.public')"></i>
</div>
</div> </div>
</div> </div>
<div style="position:relative;" v-if="candidates"> <div style="position:relative;" v-if="candidates">

View file

@ -399,6 +399,9 @@ const en = {
unlisted: 'Unlisted - Do not post to public timelines', unlisted: 'Unlisted - Do not post to public timelines',
private: 'Followers-only - Post to followers only', private: 'Followers-only - Post to followers only',
direct: 'Direct - Post to mentioned users only' direct: 'Direct - Post to mentioned users only'
},
content_type: {
plain_text: 'Plain text'
} }
}, },
finder: { finder: {

View file

@ -103,23 +103,29 @@ window.fetch('/api/statusnet/config.json')
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
var staticConfig = data var staticConfig = data
// This takes static config and overrides properties that are present in apiConfig
var config = Object.assign({}, staticConfig, apiConfig)
var theme = (apiConfig.theme || staticConfig.theme) var theme = (config.theme)
var background = (apiConfig.background || staticConfig.background) var background = (config.background)
var logo = (apiConfig.logo || staticConfig.logo) var logo = (config.logo)
var redirectRootNoLogin = (apiConfig.redirectRootNoLogin || staticConfig.redirectRootNoLogin) var logoMask = (typeof config.logoMask === 'undefined' ? true : config.logoMask)
var redirectRootLogin = (apiConfig.redirectRootLogin || staticConfig.redirectRootLogin) var logoMargin = (typeof config.logoMargin === 'undefined' ? 0 : config.logoMargin)
var chatDisabled = (apiConfig.chatDisabled || staticConfig.chatDisabled) var redirectRootNoLogin = (config.redirectRootNoLogin)
var showWhoToFollowPanel = (apiConfig.showWhoToFollowPanel || staticConfig.showWhoToFollowPanel) var redirectRootLogin = (config.redirectRootLogin)
var whoToFollowProvider = (apiConfig.whoToFollowProvider || staticConfig.whoToFollowProvider) var chatDisabled = (config.chatDisabled)
var whoToFollowLink = (apiConfig.whoToFollowLink || staticConfig.whoToFollowLink) var showWhoToFollowPanel = (config.showWhoToFollowPanel)
var showInstanceSpecificPanel = (apiConfig.showInstanceSpecificPanel || staticConfig.showInstanceSpecificPanel) var whoToFollowProvider = (config.whoToFollowProvider)
var scopeOptionsEnabled = (apiConfig.scopeOptionsEnabled || staticConfig.scopeOptionsEnabled) var whoToFollowLink = (config.whoToFollowLink)
var collapseMessageWithSubject = (apiConfig.collapseMessageWithSubject || staticConfig.collapseMessageWithSubject) var showInstanceSpecificPanel = (config.showInstanceSpecificPanel)
var scopeOptionsEnabled = (config.scopeOptionsEnabled)
var collapseMessageWithSubject = (config.collapseMessageWithSubject)
store.dispatch('setOption', { name: 'theme', value: theme }) store.dispatch('setOption', { name: 'theme', value: theme })
store.dispatch('setOption', { name: 'background', value: background }) store.dispatch('setOption', { name: 'background', value: background })
store.dispatch('setOption', { name: 'logo', value: logo }) store.dispatch('setOption', { name: 'logo', value: logo })
store.dispatch('setOption', { name: 'logoMask', value: logoMask })
store.dispatch('setOption', { name: 'logoMargin', value: logoMargin })
store.dispatch('setOption', { name: 'showWhoToFollowPanel', value: showWhoToFollowPanel }) store.dispatch('setOption', { name: 'showWhoToFollowPanel', value: showWhoToFollowPanel })
store.dispatch('setOption', { name: 'whoToFollowProvider', value: whoToFollowProvider }) store.dispatch('setOption', { name: 'whoToFollowProvider', value: whoToFollowProvider })
store.dispatch('setOption', { name: 'whoToFollowLink', value: whoToFollowLink }) store.dispatch('setOption', { name: 'whoToFollowLink', value: whoToFollowLink })

View file

@ -373,7 +373,7 @@ const unretweet = ({ id, credentials }) => {
}) })
} }
const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId}) => { const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType}) => {
const idsText = mediaIds.join(',') const idsText = mediaIds.join(',')
const form = new FormData() const form = new FormData()
@ -382,6 +382,7 @@ const postStatus = ({credentials, status, spoilerText, visibility, sensitive, me
if (spoilerText) form.append('spoiler_text', spoilerText) if (spoilerText) form.append('spoiler_text', spoilerText)
if (visibility) form.append('visibility', visibility) if (visibility) form.append('visibility', visibility)
if (sensitive) form.append('sensitive', sensitive) if (sensitive) form.append('sensitive', sensitive)
if (contentType) form.append('content_type', contentType)
form.append('media_ids', idsText) form.append('media_ids', idsText)
if (inReplyToStatusId) { if (inReplyToStatusId) {
form.append('in_reply_to_status_id', inReplyToStatusId) form.append('in_reply_to_status_id', inReplyToStatusId)

View file

@ -1,10 +1,10 @@
import { map } from 'lodash' import { map } from 'lodash'
import apiService from '../api/api.service.js' import apiService from '../api/api.service.js'
const postStatus = ({ store, status, spoilerText, visibility, sensitive, media = [], inReplyToStatusId = undefined }) => { const postStatus = ({ store, status, spoilerText, visibility, sensitive, media = [], inReplyToStatusId = undefined, contentType = 'text/plain' }) => {
const mediaIds = map(media, 'id') const mediaIds = map(media, 'id')
return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId}) return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType})
.then((data) => data.json()) .then((data) => data.json())
.then((data) => { .then((data) => {
if (!data.error) { if (!data.error) {

View file

@ -3,6 +3,8 @@
"theme": "sigsegv", "theme": "sigsegv",
"background": "/static/sigsegv_s.png", "background": "/static/sigsegv_s.png",
"logo": "/static/logo.svg", "logo": "/static/logo.svg",
"logoMask": true,
"logoMargin": ".1em",
"redirectRootNoLogin": "/main/all", "redirectRootNoLogin": "/main/all",
"redirectRootLogin": "/main/friends", "redirectRootLogin": "/main/friends",
"chatDisabled": true, "chatDisabled": true,