forked from AkkomaGang/akkoma-fe
Merge branch 'develop' of ssh.gitgud.io:lambadalambda/pleroma-fe into develop
This commit is contained in:
commit
026ab7c1df
14 changed files with 88 additions and 32 deletions
|
@ -63,7 +63,7 @@ nav {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sidebar {
|
.sidebar {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-basis: 300px;
|
flex-basis: 300px;
|
||||||
}
|
}
|
||||||
|
@ -255,3 +255,8 @@ nav {
|
||||||
.fade-enter, .fade-leave-active {
|
.fade-enter, .fade-leave-active {
|
||||||
opacity: 0
|
opacity: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 2;
|
||||||
|
flex-basis: 500px;
|
||||||
|
}
|
||||||
|
|
12
src/App.vue
12
src/App.vue
|
@ -6,14 +6,16 @@
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="container" id="content">
|
<div class="container" id="content">
|
||||||
<sidebar>
|
<div class="sidebar">
|
||||||
<user-panel></user-panel>
|
<user-panel></user-panel>
|
||||||
<nav-panel></nav-panel>
|
<nav-panel></nav-panel>
|
||||||
<notifications v-if="currentUser"></notifications>
|
<notifications v-if="currentUser"></notifications>
|
||||||
</sidebar>
|
</div>
|
||||||
<transition name="fade">
|
<div class="main">
|
||||||
<router-view></router-view>
|
<transition name="fade">
|
||||||
</transition>
|
<router-view></router-view>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -3,4 +3,5 @@ $main-background: white;
|
||||||
$darkened-background: whitesmoke;
|
$darkened-background: whitesmoke;
|
||||||
$green: #0fa00f;
|
$green: #0fa00f;
|
||||||
$blue: #0095ff;
|
$blue: #0095ff;
|
||||||
|
$red: #ff0000;
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
BIN
src/assets/nsfw.png
Normal file
BIN
src/assets/nsfw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
|
@ -1,4 +1,4 @@
|
||||||
import nsfwImage from '../../assets/nsfw.jpg'
|
import nsfwImage from '../../assets/nsfw.png'
|
||||||
import fileTypeService from '../../services/file_type/file_type.service.js'
|
import fileTypeService from '../../services/file_type/file_type.service.js'
|
||||||
|
|
||||||
const Attachment = {
|
const Attachment = {
|
||||||
|
@ -7,17 +7,23 @@ const Attachment = {
|
||||||
'nsfw',
|
'nsfw',
|
||||||
'statusId'
|
'statusId'
|
||||||
],
|
],
|
||||||
data: () => ({ nsfwImage }),
|
data: () => ({
|
||||||
|
nsfwImage,
|
||||||
|
showHidden: false
|
||||||
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
type () {
|
type () {
|
||||||
return fileTypeService.fileType(this.attachment.mimetype)
|
return fileTypeService.fileType(this.attachment.mimetype)
|
||||||
|
},
|
||||||
|
hidden () {
|
||||||
|
return this.nsfw && !this.showHidden
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showNsfw () {
|
toggleHidden () {
|
||||||
this.$store.commit('setNsfw', { id: this.statusId, nsfw: false })
|
this.showHidden = !this.showHidden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Attachment
|
export default Attachment
|
||||||
|
|
|
@ -1,15 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="attachment">
|
<div class="attachment">
|
||||||
<a class="image-attachment" v-if="nsfw" v-on:click.prevent="showNsfw()">
|
<a class="image-attachment" v-if="hidden" v-on:click.prevent="toggleHidden()">
|
||||||
<img :key="nsfwImage" :src="nsfwImage"></img>
|
<img :key="nsfwImage" :src="nsfwImage"></img>
|
||||||
</a>
|
</a>
|
||||||
|
<div class="hider" v-if="nsfw && !hidden">
|
||||||
|
<a href="#" @click.prevent="toggleHidden()">Hide</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a class="image-attachment" v-if="type === 'image' && !nsfw"
|
<a class="image-attachment" v-if="type === 'image' && !hidden"
|
||||||
:href="attachment.url" target="_blank">
|
:href="attachment.url" target="_blank">
|
||||||
<img :src="attachment.url"></img>
|
<img :src="attachment.url"></img>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<video v-if="type === 'video' && !nsfw" :src="attachment.url" controls></video>
|
<video v-if="type === 'video' && !hidden" :src="attachment.url" controls></video>
|
||||||
|
|
||||||
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
|
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
|
||||||
|
|
||||||
|
@ -34,12 +37,20 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
.attachment {
|
.attachment {
|
||||||
|
|
||||||
flex: 1 0 30%;
|
flex: 1 0 30%;
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 0.2em;
|
margin: 0.2em;
|
||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
|
|
||||||
|
.hider {
|
||||||
|
position: absolute;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px;
|
||||||
|
background: rgba(230,230,230,0.6);
|
||||||
|
border-radius: 0.5em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
video {
|
video {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
|
|
|
@ -20,7 +20,9 @@ const Status = {
|
||||||
},
|
},
|
||||||
loggedIn () {
|
loggedIn () {
|
||||||
return !!this.$store.state.users.currentUser
|
return !!this.$store.state.users.currentUser
|
||||||
}
|
},
|
||||||
|
deleted () { return this.statusoid.deleted },
|
||||||
|
canDelete () { return this.statusoid.user.rights.delete_others_notice || this.statusoid.user.id == this.$store.state.users.currentUser.id }
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Attachment,
|
Attachment,
|
||||||
|
@ -31,6 +33,12 @@ const Status = {
|
||||||
methods: {
|
methods: {
|
||||||
toggleReplying () {
|
toggleReplying () {
|
||||||
this.replying = !this.replying
|
this.replying = !this.replying
|
||||||
|
},
|
||||||
|
deleteStatus () {
|
||||||
|
const confirmed = confirm('Do you really want to delete this status?')
|
||||||
|
if (confirmed) {
|
||||||
|
this.$store.dispatch('deleteStatus', { id: this.status.id })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="status-el">
|
<div class="status-el" v-if="!status.deleted">
|
||||||
<div v-if="retweet" class="media container retweet-info">
|
<div v-if="retweet" class="media container retweet-info">
|
||||||
<div class="media-left">
|
<div class="media-left">
|
||||||
<i class='fa icon-retweet'></i>
|
<i class='fa icon-retweet retweeted'></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
Retweeted by {{retweeter}}
|
Retweeted by {{retweeter}}
|
||||||
|
@ -52,6 +52,11 @@
|
||||||
</div>
|
</div>
|
||||||
<retweet-button :status=status></retweet-button>
|
<retweet-button :status=status></retweet-button>
|
||||||
<favorite-button :status=status></favorite-button>
|
<favorite-button :status=status></favorite-button>
|
||||||
|
<div v-if="canDelete">
|
||||||
|
<a href="#" v-on:click.prevent="deleteStatus">
|
||||||
|
<i class='fa icon-cancel delete-status'></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<post-status-form v-if="replying" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying"></post-status-form>
|
<post-status-form v-if="replying" :reply-to="status.id" :attentions="status.attentions" :repliedUser="status.user" v-on:posted="toggleReplying"></post-status-form>
|
||||||
|
@ -125,4 +130,11 @@
|
||||||
.status-el:last-child .status {
|
.status-el:last-child .status {
|
||||||
border: none
|
border: none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-cancel,.delete-status {
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: $red;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -18,10 +18,3 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script src="./timeline.js"></script>
|
<script src="./timeline.js"></script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.timeline.panel {
|
|
||||||
flex: 2;
|
|
||||||
flex-basis: 500px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -5,10 +5,3 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./user_profile.js"></script>
|
<script src="./user_profile.js"></script>
|
||||||
|
|
||||||
<style>
|
|
||||||
.user-profile {
|
|
||||||
flex: 2;
|
|
||||||
flex-basis: 500px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ export const prepareStatus = (status) => {
|
||||||
status.nsfw = !!status.text.match(nsfwRegex)
|
status.nsfw = !!status.text.match(nsfwRegex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set deleted flag
|
||||||
|
status.deleted = false
|
||||||
|
|
||||||
// To make the array reactive
|
// To make the array reactive
|
||||||
status.attachments = status.attachments || []
|
status.attachments = status.attachments || []
|
||||||
|
|
||||||
|
@ -261,6 +264,10 @@ export const mutations = {
|
||||||
const newStatus = find(state.allStatuses, status)
|
const newStatus = find(state.allStatuses, status)
|
||||||
newStatus.repeated = value
|
newStatus.repeated = value
|
||||||
},
|
},
|
||||||
|
setDeleted (state, { status }) {
|
||||||
|
const newStatus = find(state.allStatuses, status)
|
||||||
|
newStatus.deleted = true
|
||||||
|
},
|
||||||
setLoading (state, { timeline, value }) {
|
setLoading (state, { timeline, value }) {
|
||||||
state.timelines[timeline].loading = value
|
state.timelines[timeline].loading = value
|
||||||
},
|
},
|
||||||
|
@ -276,6 +283,10 @@ const statuses = {
|
||||||
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false }) {
|
addNewStatuses ({ rootState, commit }, { statuses, showImmediately = false, timeline = false, noIdUpdate = false }) {
|
||||||
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser })
|
commit('addNewStatuses', { statuses, showImmediately, timeline, noIdUpdate, user: rootState.users.currentUser })
|
||||||
},
|
},
|
||||||
|
deleteStatus ({ rootState, commit }, status) {
|
||||||
|
commit('setDeleted', { status })
|
||||||
|
apiService.deleteStatus({ id: status.id, credentials: rootState.users.currentUser.credentials })
|
||||||
|
},
|
||||||
favorite ({ rootState, commit }, status) {
|
favorite ({ rootState, commit }, status) {
|
||||||
// Optimistic favoriting...
|
// Optimistic favoriting...
|
||||||
commit('setFavorited', { status, value: true })
|
commit('setFavorited', { status, value: true })
|
||||||
|
|
|
@ -7,6 +7,7 @@ const FAVORITE_URL = '/api/favorites/create'
|
||||||
const UNFAVORITE_URL = '/api/favorites/destroy'
|
const UNFAVORITE_URL = '/api/favorites/destroy'
|
||||||
const RETWEET_URL = '/api/statuses/retweet'
|
const RETWEET_URL = '/api/statuses/retweet'
|
||||||
const STATUS_UPDATE_URL = '/api/statuses/update.json'
|
const STATUS_UPDATE_URL = '/api/statuses/update.json'
|
||||||
|
const STATUS_DELETE_URL = '/api/statuses/destroy'
|
||||||
const STATUS_URL = '/api/statuses/show'
|
const STATUS_URL = '/api/statuses/show'
|
||||||
const MEDIA_UPLOAD_URL = '/api/statusnet/media/upload'
|
const MEDIA_UPLOAD_URL = '/api/statusnet/media/upload'
|
||||||
const CONVERSATION_URL = '/api/statusnet/conversation'
|
const CONVERSATION_URL = '/api/statusnet/conversation'
|
||||||
|
@ -118,6 +119,13 @@ const postStatus = ({credentials, status, mediaIds, inReplyToStatusId}) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const deleteStatus = ({ id, credentials }) => {
|
||||||
|
return fetch(`${STATUS_DELETE_URL}/${id}.json`, {
|
||||||
|
headers: authHeaders(credentials),
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const uploadMedia = ({formData, credentials}) => {
|
const uploadMedia = ({formData, credentials}) => {
|
||||||
return fetch(MEDIA_UPLOAD_URL, {
|
return fetch(MEDIA_UPLOAD_URL, {
|
||||||
body: formData,
|
body: formData,
|
||||||
|
@ -139,6 +147,7 @@ const apiService = {
|
||||||
unfavorite,
|
unfavorite,
|
||||||
retweet,
|
retweet,
|
||||||
postStatus,
|
postStatus,
|
||||||
|
deleteStatus,
|
||||||
uploadMedia
|
uploadMedia
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,11 @@ describe('Statuses.prepareStatus', () => {
|
||||||
|
|
||||||
expect(prepareStatus(nsfw).nsfw).to.eq(false)
|
expect(prepareStatus(nsfw).nsfw).to.eq(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('sets deleted flag to false', () => {
|
||||||
|
const aStatus = makeMockStatus({id: 1, text: 'Hello oniichan'})
|
||||||
|
expect(prepareStatus(aStatus).deleted).to.eq(false)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Statuses.findMaxId', () => {
|
describe('Statuses.findMaxId', () => {
|
||||||
|
|
Loading…
Reference in a new issue