Show announcement dates

This commit is contained in:
Tusooa Zhu 2022-03-17 16:51:32 -04:00 committed by tusooa
parent ce84557190
commit 04fbb6d93d
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
8 changed files with 156 additions and 58 deletions

View File

@ -1,6 +1,21 @@
import { mapState } from 'vuex' import { mapState } from 'vuex'
import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
import localeService from '../../services/locale/locale.service.js'
const Announcement = { const Announcement = {
components: {
AnnouncementEditor
},
data () {
return {
editing: false,
newAnnouncement: {
content: '',
startsAt: undefined,
endsAt: undefined
}
}
},
props: { props: {
announcement: Object announcement: Object
}, },
@ -13,6 +28,22 @@ const Announcement = {
}, },
isRead () { isRead () {
return this.announcement.read return this.announcement.read
},
startsAt () {
const time = this.announcement['starts_at']
if (!time) {
return
}
return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale))
},
endsAt () {
const time = this.announcement['ends_at']
if (!time) {
return
}
return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale))
} }
}, },
methods: { methods: {
@ -23,6 +54,10 @@ const Announcement = {
}, },
deleteAnnouncement () { deleteAnnouncement () {
return this.$store.dispatch('deleteAnnouncement', this.announcement.id) return this.$store.dispatch('deleteAnnouncement', this.announcement.id)
},
formatTimeOrDate (time, locale) {
const d = new Date(time)
return this.announcement['all_day'] ? d.toLocaleDateString(locale) : d.toLocaleString(locale)
} }
} }
} }

View File

@ -5,12 +5,26 @@
</div> </div>
<div class="body"> <div class="body">
<rich-content <rich-content
v-if="!editing"
:html="content" :html="content"
:emoji="announcement.emojis" :emoji="announcement.emojis"
:handle-links="true" :handle-links="true"
/> />
<announcement-editor
v-else
:announcement="newAnnouncement"
/>
</div> </div>
<div class="footer"> <div class="footer">
<div class="times">
<span v-if="startsAt">
{{ $t('announcements.start_time_display', { time: startsAt }) }}
</span>
<span v-if="endsAt">
{{ $t('announcements.end_time_display', { time: endsAt }) }}
</span>
</div>
<div class="actions">
<button <button
v-if="currentUser" v-if="currentUser"
class="btn button-default" class="btn button-default"
@ -28,6 +42,7 @@
</button> </button>
</div> </div>
</div> </div>
</div>
</template> </template>
<script src="./announcement.js"></script> <script src="./announcement.js"></script>
@ -47,6 +62,15 @@
} }
.footer { .footer {
display: flex;
flex-direction: column;
.times {
display: flex;
flex-direction: column;
}
}
.footer .actions {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-around; justify-content: space-around;

View File

@ -0,0 +1,13 @@
import Checkbox from '../checkbox/checkbox.vue'
const AnnouncementEditor = {
components: {
Checkbox
},
props: {
announcement: Object,
disabled: Boolean
}
}
export default AnnouncementEditor

View File

@ -0,0 +1,52 @@
<template>
<div class="announcement-editor">
<textarea
ref="textarea"
v-model="announcement.content"
class="post-textarea"
rows="1"
cols="1"
:placeholder="$t('announcements.post_placeholder')"
:disabled="disabled"
/>
<span class="announcement-metadata">
<label for="announcement-start-time">{{ $t('announcements.start_time_prompt') }}</label>
<input
id="announcement-start-time"
v-model="announcement.startsAt"
:type="announcement.allDay ? 'date' : 'datetime-local'"
:disabled="disabled"
>
</span>
<span class="announcement-metadata">
<label for="announcement-end-time">{{ $t('announcements.end_time_prompt') }}</label>
<input
id="announcement-end-time"
v-model="announcement.endsAt"
:type="announcement.allDay ? 'date' : 'datetime-local'"
:disabled="disabled"
>
</span>
<span class="announcement-metadata">
<Checkbox
id="announcement-all-day"
v-model="announcement.allDay"
:disabled="disabled"
/>
<label for="announcement-all-day">{{ $t('announcements.all_day_prompt') }}</label>
</span>
</div>
</template>
<script src="./announcement_editor.js"></script>
<style lang="scss">
.announcement-editor {
display: flex;
align-items: stretch;
flex-direction: column;
.announcement-metadata {
margin-top: 0.5em;
}
}
</style>

View File

@ -1,11 +1,11 @@
import { mapState } from 'vuex' import { mapState } from 'vuex'
import Announcement from '../announcement/announcement.vue' import Announcement from '../announcement/announcement.vue'
import Checkbox from '../checkbox/checkbox.vue' import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
const AnnouncementsPage = { const AnnouncementsPage = {
components: { components: {
Announcement, Announcement,
Checkbox AnnouncementEditor
}, },
data () { data () {
return { return {

View File

@ -14,38 +14,10 @@
<h4>{{ $t('announcements.post_form_header') }}</h4> <h4>{{ $t('announcements.post_form_header') }}</h4>
</div> </div>
<div class="body"> <div class="body">
<textarea <announcement-editor
ref="textarea" :announcement="newAnnouncement"
v-model="newAnnouncement.content"
class="post-textarea"
rows="1"
cols="1"
:placeholder="$t('announcements.post_placeholder')"
:disabled="posting" :disabled="posting"
/> />
<span class="announcement-metadata">
<label for="announcement-start-time">{{ $t('announcements.start_time_prompt') }}</label>
<input
id="announcement-start-time"
v-model="newAnnouncement.startsAt"
:type="newAnnouncement.allDay ? 'date' : 'datetime-local'"
>
</span>
<span class="announcement-metadata">
<label for="announcement-end-time">{{ $t('announcements.end_time_prompt') }}</label>
<input
id="announcement-end-time"
v-model="newAnnouncement.endsAt"
:type="newAnnouncement.allDay ? 'date' : 'datetime-local'"
>
</span>
<span class="announcement-metadata">
<Checkbox
id="announcement-all-day"
v-model="newAnnouncement.allDay"
/>
<label for="announcement-all-day">{{ $t('announcements.all_day_prompt') }}</label>
</span>
</div> </div>
<div class="footer"> <div class="footer">
<button <button
@ -99,15 +71,6 @@
margin-bottom: var(--status-margin, $status-margin); margin-bottom: var(--status-margin, $status-margin);
} }
.body {
display: flex;
align-items: stretch;
flex-direction: column;
.announcement-metadata {
margin-top: 0.5em;
}
}
.post-textarea { .post-textarea {
resize: vertical; resize: vertical;
height: 10em; height: 10em;

View File

@ -28,7 +28,12 @@ const announcements = {
mutations, mutations,
actions: { actions: {
fetchAnnouncements (store) { fetchAnnouncements (store) {
return store.rootState.api.backendInteractor.fetchAnnouncements() const currentUser = store.rootState.users.currentUser
const isAdmin = currentUser && currentUser.role === 'admin'
return (isAdmin
? store.rootState.api.backendInteractor.adminFetchAnnouncements()
: store.rootState.api.backendInteractor.fetchAnnouncements())
.then(announcements => { .then(announcements => {
store.commit('setAnnouncements', announcements) store.commit('setAnnouncements', announcements)
}) })

View File

@ -102,6 +102,7 @@ const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}` const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}`
const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports' const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports'
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups' const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
@ -1365,6 +1366,10 @@ const dismissNotification = ({ credentials, id }) => {
}) })
} }
const adminFetchAnnouncements = ({ credentials }) => {
return promisedRequest({ url: PLEROMA_ANNOUNCEMENTS_URL, credentials })
}
const fetchAnnouncements = ({ credentials }) => { const fetchAnnouncements = ({ credentials }) => {
return promisedRequest({ url: MASTODON_ANNOUNCEMENTS_URL, credentials }) return promisedRequest({ url: MASTODON_ANNOUNCEMENTS_URL, credentials })
} }
@ -1738,7 +1743,8 @@ const apiService = {
fetchAnnouncements, fetchAnnouncements,
dismissAnnouncement, dismissAnnouncement,
postAnnouncement, postAnnouncement,
deleteAnnouncement deleteAnnouncement,
adminFetchAnnouncements
} }
export default apiService export default apiService