forked from AkkomaGang/akkoma-fe
Merge branch 'develop' into feature/normal-emoji-completion
This commit is contained in:
commit
36e68fba96
13 changed files with 105 additions and 29 deletions
|
@ -25,6 +25,7 @@
|
||||||
"sanitize-html": "^1.13.0",
|
"sanitize-html": "^1.13.0",
|
||||||
"sass-loader": "^4.0.2",
|
"sass-loader": "^4.0.2",
|
||||||
"vue": "^2.3.4",
|
"vue": "^2.3.4",
|
||||||
|
"vue-chat-scroll": "^1.2.1",
|
||||||
"vue-i18n": "^7.3.2",
|
"vue-i18n": "^7.3.2",
|
||||||
"vue-router": "^2.5.3",
|
"vue-router": "^2.5.3",
|
||||||
"vue-template-compiler": "^2.3.4",
|
"vue-template-compiler": "^2.3.4",
|
||||||
|
|
|
@ -2,6 +2,7 @@ import UserPanel from './components/user_panel/user_panel.vue'
|
||||||
import NavPanel from './components/nav_panel/nav_panel.vue'
|
import NavPanel from './components/nav_panel/nav_panel.vue'
|
||||||
import Notifications from './components/notifications/notifications.vue'
|
import Notifications from './components/notifications/notifications.vue'
|
||||||
import UserFinder from './components/user_finder/user_finder.vue'
|
import UserFinder from './components/user_finder/user_finder.vue'
|
||||||
|
import ChatPanel from './components/chat_panel/chat_panel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
@ -9,7 +10,8 @@ export default {
|
||||||
UserPanel,
|
UserPanel,
|
||||||
NavPanel,
|
NavPanel,
|
||||||
Notifications,
|
Notifications,
|
||||||
UserFinder
|
UserFinder,
|
||||||
|
ChatPanel
|
||||||
},
|
},
|
||||||
data: () => ({
|
data: () => ({
|
||||||
mobileActivePanel: 'timeline'
|
mobileActivePanel: 'timeline'
|
||||||
|
@ -21,7 +23,8 @@ export default {
|
||||||
},
|
},
|
||||||
logoStyle () { return { 'background-image': `url(${this.$store.state.config.logo})` } },
|
logoStyle () { return { 'background-image': `url(${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 }
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
activatePanel (panelName) {
|
activatePanel (panelName) {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<user-panel></user-panel>
|
<user-panel></user-panel>
|
||||||
<nav-panel></nav-panel>
|
<nav-panel></nav-panel>
|
||||||
|
<chat-panel v-if="currentUser && chat"></chat-panel>
|
||||||
<notifications v-if="currentUser"></notifications>
|
<notifications v-if="currentUser"></notifications>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const chat = {
|
const chatPanel = {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
currentMessage: '',
|
currentMessage: '',
|
||||||
|
@ -18,4 +18,4 @@ const chat = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default chat
|
export default chatPanel
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="chat-panel panel panel-default">
|
<div class="chat-panel">
|
||||||
|
<div class="panel panel-default base01-background">
|
||||||
<div class="panel-heading timeline-heading base02-background base04">
|
<div class="panel-heading timeline-heading base02-background base04">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{$t('chat.title')}}
|
{{$t('chat.title')}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body base01-background">
|
<div class="chat-window" v-chat-scroll>
|
||||||
<div class="chat-window">
|
|
||||||
<div class="chat-message" v-for="message in messages" :key="message.id">
|
<div class="chat-message" v-for="message in messages" :key="message.id">
|
||||||
<span class="chat-avatar">
|
<span class="chat-avatar">
|
||||||
<img :src="message.author.avatar" />
|
<img :src="message.author.avatar" />
|
||||||
|
@ -26,12 +26,11 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./chat.js"></script>
|
<script src="./chat_panel.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.chat-window {
|
.chat-window {
|
||||||
max-height: 80vh;
|
max-height: 200px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
|
@ -7,11 +7,6 @@
|
||||||
{{ $t("nav.timeline") }}
|
{{ $t("nav.timeline") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
<li v-if='chat && currentUser'>
|
|
||||||
<router-link class="base00-background" to='/chat'>
|
|
||||||
{{ $t("nav.chat") }}
|
|
||||||
</router-link>
|
|
||||||
</li>
|
|
||||||
<li v-if='currentUser'>
|
<li v-if='currentUser'>
|
||||||
<router-link class="base00-background" :to="{ name: 'mentions', params: { username: currentUser.screen_name } }">
|
<router-link class="base00-background" :to="{ name: 'mentions', params: { username: currentUser.screen_name } }">
|
||||||
{{ $t("nav.mentions") }}
|
{{ $t("nav.mentions") }}
|
||||||
|
|
|
@ -5,7 +5,10 @@ const UserSettings = {
|
||||||
return {
|
return {
|
||||||
newname: this.$store.state.users.currentUser.name,
|
newname: this.$store.state.users.currentUser.name,
|
||||||
newbio: this.$store.state.users.currentUser.description,
|
newbio: this.$store.state.users.currentUser.description,
|
||||||
uploading: [ false, false, false ],
|
followList: null,
|
||||||
|
followImportError: false,
|
||||||
|
followsImported: false,
|
||||||
|
uploading: [ false, false, false, false ],
|
||||||
previews: [ null, null, null ]
|
previews: [ null, null, null ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -15,6 +18,9 @@ const UserSettings = {
|
||||||
computed: {
|
computed: {
|
||||||
user () {
|
user () {
|
||||||
return this.$store.state.users.currentUser
|
return this.$store.state.users.currentUser
|
||||||
|
},
|
||||||
|
pleromaBackend () {
|
||||||
|
return this.$store.state.config.pleromaBackend
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -117,6 +123,29 @@ const UserSettings = {
|
||||||
}
|
}
|
||||||
this.uploading[2] = false
|
this.uploading[2] = false
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
importFollows () {
|
||||||
|
this.uploading[3] = true
|
||||||
|
const followList = this.followList
|
||||||
|
this.$store.state.api.backendInteractor.followImport({params: followList})
|
||||||
|
.then((status) => {
|
||||||
|
if (status) {
|
||||||
|
this.followsImported = true
|
||||||
|
} else {
|
||||||
|
this.followImportError = true
|
||||||
|
}
|
||||||
|
this.uploading[3] = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
followListChange () {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
let formData = new FormData()
|
||||||
|
formData.append('list', this.$refs.followlist.files[0])
|
||||||
|
this.followList = formData
|
||||||
|
},
|
||||||
|
dismissImported () {
|
||||||
|
this.followsImported = false
|
||||||
|
this.followImportError = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,23 @@
|
||||||
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
|
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
|
||||||
<button class="btn btn-default base05 base02-background" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
|
<button class="btn btn-default base05 base02-background" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="setting-item" v-if="pleromaBackend">
|
||||||
|
<h3>{{$t('settings.follow_import')}}</h3>
|
||||||
|
<p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
|
||||||
|
<form v-model="followImportForm">
|
||||||
|
<input type="file" ref="followlist" v-on:change="followListChange"></input>
|
||||||
|
</form>
|
||||||
|
<i class="base09 icon-spin4 animate-spin uploading" v-if="uploading[3]"></i>
|
||||||
|
<button class="btn btn-default base05 base02-background" v-else @click="importFollows">{{$t('general.submit')}}</button>
|
||||||
|
<div v-if="followsImported">
|
||||||
|
<i class="icon-cross" @click="dismissImported"></i>
|
||||||
|
<p>{{$t('settings.follows_imported')}}</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="followImportError">
|
||||||
|
<i class="icon-cross" @click="dismissImported"</i>
|
||||||
|
<p>{{$t('settings.follow_import_error')}}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -58,7 +58,11 @@ const de = {
|
||||||
nsfw_clickthrough: 'Aktiviere ausblendbares Overlay für als NSFW markierte Anhänge',
|
nsfw_clickthrough: 'Aktiviere ausblendbares Overlay für als NSFW markierte Anhänge',
|
||||||
autoload: 'Aktiviere automatisches Laden von älteren Beiträgen beim scrollen',
|
autoload: 'Aktiviere automatisches Laden von älteren Beiträgen beim scrollen',
|
||||||
streaming: 'Aktiviere automatisches Laden (Streaming) von neuen Beiträgen',
|
streaming: 'Aktiviere automatisches Laden (Streaming) von neuen Beiträgen',
|
||||||
reply_link_preview: 'Aktiviere reply-link Vorschau bei Maus-Hover'
|
reply_link_preview: 'Aktiviere reply-link Vorschau bei Maus-Hover',
|
||||||
|
follow_import: 'Folgeliste importieren',
|
||||||
|
import_followers_from_a_csv_file: 'Importiere Kontakte, denen du folgen möchtest, aus einer CSV-Datei',
|
||||||
|
follows_imported: 'Folgeliste importiert! Die Bearbeitung kann eine Zeit lang dauern.',
|
||||||
|
follow_import_error: 'Fehler beim importieren der Folgeliste'
|
||||||
},
|
},
|
||||||
notifications: {
|
notifications: {
|
||||||
notifications: 'Benachrichtigungen',
|
notifications: 'Benachrichtigungen',
|
||||||
|
@ -242,7 +246,11 @@ const en = {
|
||||||
nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding',
|
nsfw_clickthrough: 'Enable clickthrough NSFW attachment hiding',
|
||||||
autoload: 'Enable automatic loading when scrolled to the bottom',
|
autoload: 'Enable automatic loading when scrolled to the bottom',
|
||||||
streaming: 'Enable automatic streaming of new posts when scrolled to the top',
|
streaming: 'Enable automatic streaming of new posts when scrolled to the top',
|
||||||
reply_link_preview: 'Enable reply-link preview on mouse hover'
|
reply_link_preview: 'Enable reply-link preview on mouse hover',
|
||||||
|
follow_import: 'Follow import',
|
||||||
|
import_followers_from_a_csv_file: 'Import followers from a csv file',
|
||||||
|
follows_imported: 'Follows imported! Processing them will take a while.',
|
||||||
|
follow_import_error: 'Error importing followers'
|
||||||
},
|
},
|
||||||
notifications: {
|
notifications: {
|
||||||
notifications: 'Notifications',
|
notifications: 'Notifications',
|
||||||
|
|
12
src/main.js
12
src/main.js
|
@ -12,7 +12,6 @@ import UserProfile from './components/user_profile/user_profile.vue'
|
||||||
import Settings from './components/settings/settings.vue'
|
import Settings from './components/settings/settings.vue'
|
||||||
import Registration from './components/registration/registration.vue'
|
import Registration from './components/registration/registration.vue'
|
||||||
import UserSettings from './components/user_settings/user_settings.vue'
|
import UserSettings from './components/user_settings/user_settings.vue'
|
||||||
import Chat from './components/chat/chat.vue'
|
|
||||||
|
|
||||||
import statusesModule from './modules/statuses.js'
|
import statusesModule from './modules/statuses.js'
|
||||||
import usersModule from './modules/users.js'
|
import usersModule from './modules/users.js'
|
||||||
|
@ -27,6 +26,8 @@ import createPersistedState from './lib/persisted_state.js'
|
||||||
|
|
||||||
import messages from './i18n/messages.js'
|
import messages from './i18n/messages.js'
|
||||||
|
|
||||||
|
import VueChatScroll from 'vue-chat-scroll'
|
||||||
|
|
||||||
const currentLocale = (window.navigator.language || 'en').split('-')[0]
|
const currentLocale = (window.navigator.language || 'en').split('-')[0]
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
@ -39,6 +40,7 @@ Vue.use(VueTimeago, {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
|
Vue.use(VueChatScroll)
|
||||||
|
|
||||||
const persistedStateOptions = {
|
const persistedStateOptions = {
|
||||||
paths: [
|
paths: [
|
||||||
|
@ -97,8 +99,7 @@ window.fetch('/static/config.json')
|
||||||
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
{ name: 'mentions', path: '/:username/mentions', component: Mentions },
|
||||||
{ name: 'settings', path: '/settings', component: Settings },
|
{ name: 'settings', path: '/settings', component: Settings },
|
||||||
{ name: 'registration', path: '/registration', component: Registration },
|
{ name: 'registration', path: '/registration', component: Registration },
|
||||||
{ name: 'user-settings', path: '/user-settings', component: UserSettings },
|
{ name: 'user-settings', path: '/user-settings', component: UserSettings }
|
||||||
{ name: 'chat', path: '/chat', component: Chat }
|
|
||||||
]
|
]
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
|
@ -137,8 +138,11 @@ window.fetch('/api/pleroma/emoji.json')
|
||||||
return { shortcode: key, image_url: values[key] }
|
return { shortcode: key, image_url: values[key] }
|
||||||
})
|
})
|
||||||
store.dispatch('setOption', { name: 'customEmoji', value: emoji })
|
store.dispatch('setOption', { name: 'customEmoji', value: emoji })
|
||||||
|
store.dispatch('setOption', { name: 'pleromaBackend', value: true })
|
||||||
},
|
},
|
||||||
(failure) => {}
|
(failure) => {
|
||||||
|
store.dispatch('setOption', { name: 'pleromaBackend', value: false })
|
||||||
|
}
|
||||||
),
|
),
|
||||||
(error) => console.log(error)
|
(error) => console.log(error)
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,7 @@ const QVITTER_USER_TIMELINE_URL = '/api/qvitter/statuses/user_timeline.json'
|
||||||
const BLOCKING_URL = '/api/blocks/create.json'
|
const BLOCKING_URL = '/api/blocks/create.json'
|
||||||
const UNBLOCKING_URL = '/api/blocks/destroy.json'
|
const UNBLOCKING_URL = '/api/blocks/destroy.json'
|
||||||
const USER_URL = '/api/users/show.json'
|
const USER_URL = '/api/users/show.json'
|
||||||
|
const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
|
||||||
|
|
||||||
import { each, map } from 'lodash'
|
import { each, map } from 'lodash'
|
||||||
import 'whatwg-fetch'
|
import 'whatwg-fetch'
|
||||||
|
@ -362,6 +363,15 @@ const uploadMedia = ({formData, credentials}) => {
|
||||||
.then((text) => (new DOMParser()).parseFromString(text, 'application/xml'))
|
.then((text) => (new DOMParser()).parseFromString(text, 'application/xml'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const followImport = ({params, credentials}) => {
|
||||||
|
return fetch(FOLLOW_IMPORT_URL, {
|
||||||
|
body: params,
|
||||||
|
method: 'POST',
|
||||||
|
headers: authHeaders(credentials)
|
||||||
|
})
|
||||||
|
.then((response) => response.ok)
|
||||||
|
}
|
||||||
|
|
||||||
const fetchMutes = ({credentials}) => {
|
const fetchMutes = ({credentials}) => {
|
||||||
const url = '/api/qvitter/mutes.json'
|
const url = '/api/qvitter/mutes.json'
|
||||||
|
|
||||||
|
@ -396,7 +406,8 @@ const apiService = {
|
||||||
updateBg,
|
updateBg,
|
||||||
updateProfile,
|
updateProfile,
|
||||||
updateBanner,
|
updateBanner,
|
||||||
externalProfile
|
externalProfile,
|
||||||
|
followImport
|
||||||
}
|
}
|
||||||
|
|
||||||
export default apiService
|
export default apiService
|
||||||
|
|
|
@ -59,6 +59,7 @@ const backendInteractorService = (credentials) => {
|
||||||
const updateProfile = ({params}) => apiService.updateProfile({credentials, params})
|
const updateProfile = ({params}) => apiService.updateProfile({credentials, params})
|
||||||
|
|
||||||
const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials})
|
const externalProfile = (profileUrl) => apiService.externalProfile({profileUrl, credentials})
|
||||||
|
const followImport = ({params}) => apiService.followImport({params, credentials})
|
||||||
|
|
||||||
const backendInteractorServiceInstance = {
|
const backendInteractorServiceInstance = {
|
||||||
fetchStatus,
|
fetchStatus,
|
||||||
|
@ -80,7 +81,8 @@ const backendInteractorService = (credentials) => {
|
||||||
updateBg,
|
updateBg,
|
||||||
updateBanner,
|
updateBanner,
|
||||||
updateProfile,
|
updateProfile,
|
||||||
externalProfile
|
externalProfile,
|
||||||
|
followImport
|
||||||
}
|
}
|
||||||
|
|
||||||
return backendInteractorServiceInstance
|
return backendInteractorServiceInstance
|
||||||
|
|
|
@ -5696,6 +5696,12 @@ void-elements@^2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
|
||||||
|
|
||||||
|
vue-chat-scroll@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/vue-chat-scroll/-/vue-chat-scroll-1.2.1.tgz#54f123004b887d91f2f7fb69b9bebdf6f61ea9b4"
|
||||||
|
dependencies:
|
||||||
|
vue "^2.1.10"
|
||||||
|
|
||||||
vue-hot-reload-api@^2.0.1:
|
vue-hot-reload-api@^2.0.1:
|
||||||
version "2.0.9"
|
version "2.0.9"
|
||||||
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.0.9.tgz#2e8cfbfc8e531eea57d8c1f0bd761047c7e11b56"
|
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.0.9.tgz#2e8cfbfc8e531eea57d8c1f0bd761047c7e11b56"
|
||||||
|
@ -5747,7 +5753,7 @@ vue-timeago@^3.1.2:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-timeago/-/vue-timeago-3.2.0.tgz#73fd0635de6ea4ecfbbce035b2e44035d806fba1"
|
resolved "https://registry.yarnpkg.com/vue-timeago/-/vue-timeago-3.2.0.tgz#73fd0635de6ea4ecfbbce035b2e44035d806fba1"
|
||||||
|
|
||||||
vue@^2.3.4:
|
vue@^2.1.10, vue@^2.3.4:
|
||||||
version "2.3.4"
|
version "2.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.4.tgz#5ec3b87a191da8090bbef56b7cfabd4158038171"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.3.4.tgz#5ec3b87a191da8090bbef56b7cfabd4158038171"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue