Merge branch 'dev' into feat/add_user_theme_view_controls

This commit is contained in:
lesion
2023-02-03 15:18:16 +01:00
117 changed files with 4890 additions and 2443 deletions

View File

@@ -25,6 +25,18 @@ v-container.container.pa-0.pa-md-3
v-tab(href='#places') {{$t('common.places')}}
v-tab-item(value='places')
Places
//- TAGS
v-tab(href='#tags') {{$t('common.tags')}}
v-tab-item(value='tags')
Tags
//- GEOCODING / MAPS
v-tab(href='#geolocation' v-if='settings.allow_geolocation') {{$t('admin.geolocation')}}
v-tab-item(value='geolocation')
client-only(placeholder='Loading...')
Geolocation
//- Collections
v-tab(href='#collections') {{$t('common.collections')}}
@@ -70,7 +82,9 @@ export default {
Users: () => import(/* webpackChunkName: "admin" */'../components/admin/Users'),
Events: () => import(/* webpackChunkName: "admin" */'../components/admin/Events'),
Places: () => import(/* webpackChunkName: "admin" */'../components/admin/Places'),
Tags: () => import(/* webpackChunkName: "admin" */'../components/admin/Tags'),
Collections: () => import(/* webpackChunkName: "admin" */'../components/admin/Collections'),
[process.client && 'Geolocation']: () => import(/* webpackChunkName: "admin" */'../components/admin/Geolocation.vue'),
Federation: () => import(/* webpackChunkName: "admin" */'../components/admin/Federation.vue'),
Moderation: () => import(/* webpackChunkName: "admin" */'../components/admin/Moderation.vue'),
Plugin: () => import(/* webpackChunkName: "admin" */'../components/admin/Plugin.vue'),

View File

@@ -91,17 +91,33 @@ export default {
WhereInput,
DateInput
},
validate({ store }) {
return (store.state.auth.loggedIn || store.state.settings.allow_anon_event)
validate({ store, params, error }) {
// should we allow anon event?
if(!store.state.settings.allow_anon_event && !store.state.auth.loggedIn) {
return error({ statusCode: 401, message: 'Not allowed'})
}
// do not allow edit to anon users
if (params.edit && !store.state.auth.loggedIn) {
return error({ statusCode: 401, message: 'Not allowed'})
}
return true
},
async asyncData({ params, $axios, error }) {
async asyncData({ params, $axios, error, $auth, store }) {
if (params.edit) {
const data = { event: { place: {}, media: [] } }
data.id = params.edit
data.edit = true
let event
try {
event = await $axios.$get('/event/' + data.id)
event = await $axios.$get('/event/detail/' + data.id)
if (!$auth.user.is_admin && $auth.user.id !== event.userId) {
error({ statusCode: 401, message: 'Not allowed' })
return {}
}
} catch (e) {
error({ statusCode: 404, message: 'Event not found!' })
return {}
@@ -228,6 +244,8 @@ export default {
if (this.date.dueHour) {
[hour, minute] = this.date.dueHour.split(':')
formData.append('end_datetime', dayjs(this.date.due).hour(Number(hour)).minute(Number(minute)).second(0).unix())
} else if (!!this.date.multidate) {
formData.append('end_datetime', dayjs(this.date.due).hour(24).minute(0).second(0).unix())
}
if (this.edit) {

View File

@@ -31,7 +31,7 @@ export default {
async asyncData ({ $axios, params, error }) {
try {
const collection = params.collection
const events = await $axios.$get(`/collections/${collection}`)
const events = await $axios.$get(`/collections/${encodeURIComponent(collection)}`)
return { events, collection }
} catch (e) {
console.error(e)

View File

@@ -17,7 +17,7 @@ export default {
layout: 'iframe',
async asyncData ({ $axios, params, error }) {
try {
const event = await $axios.$get(`/event/${params.event_id}`)
const event = await $axios.$get(`/event/detail/${params.event_id}`)
return { event }
} catch (e) {
error({ statusCode: 404, message: 'Event not found' })

View File

@@ -3,7 +3,7 @@ v-container#event.pa-0.pa-sm-2
//- EVENT PAGE
//- gancio supports microformats (http://microformats.org/wiki/h-event)
//- and microdata https://schema.org/Event
v-card.h-event(itemscope itemtype="https://schema.org/Event")
v-card.h-event(itemscope itemtype="https://schema.org/Event" v-touch="{ left: goNext, right: goPrev }")
v-card-text
v-row
@@ -28,13 +28,13 @@ v-container#event.pa-0.pa-sm-2
.text-h6.p-location.h-adr(itemprop="location" itemscope itemtype="https://schema.org/Place")
v-icon(v-text='mdiMapMarker' small)
nuxt-link.vcard.ml-2.p-name.text-decoration-none.text-button(itemprop="name" :to='`/place/${event.place.name}`') {{event.place && event.place.name}}
nuxt-link.vcard.ml-2.p-name.text-decoration-none.text-button(itemprop="name" :to='`/place/${encodeURIComponent(event.place.name)}`') {{event.place && event.place.name}}
.text-caption.p-street-address(itemprop='address') {{event.place && event.place.address}}
//- tags, hashtags
v-card-text.pt-0(v-if='event.tags && event.tags.length')
v-chip.p-category.ml-1.mt-1(v-for='tag in event.tags' small label color='primary'
outlined :key='tag' :to='`/tag/${tag}`') {{tag}}
outlined :key='tag' :to='`/tag/${encodeURIComponent(tag)}`') {{tag}}
v-divider
//- info & actions
@@ -185,7 +185,7 @@ export default {
},
async asyncData ({ $axios, params, error }) {
try {
const event = await $axios.$get(`/event/${params.slug}`)
const event = await $axios.$get(`/event/detail/${params.slug}`)
return { event }
} catch (e) {
error({ statusCode: 404, message: 'Event not found' })
@@ -318,12 +318,22 @@ export default {
keyDown (ev) {
if (ev.altKey || ev.ctrlKey || ev.metaKey || ev.shiftKey) { return }
if (ev.key === 'ArrowRight' && this.event.next) {
this.$router.replace(`/event/${this.event.next}`)
this.goNext()
}
if (ev.key === 'ArrowLeft' && this.event.prev) {
this.goPrev()
}
},
goPrev () {
if (this.event.prev) {
this.$router.replace(`/event/${this.event.prev}`)
}
},
goNext () {
if (this.event.next) {
this.$router.replace(`/event/${this.event.next}`)
}
},
showResource (resource) {
this.showResources = true
this.selectedResource = resource

View File

@@ -27,8 +27,11 @@ export default {
name: 'Index',
components: { Event, Announcement, ThemeView },
middleware: 'setup',
async fetch () {
return this.getEvents()
fetch () {
return this.getEvents({
start: this.start,
end: this.end
})
},
activated() {
if (this.$fetchState.timestamp <= Date.now() - 60000) {
@@ -40,15 +43,13 @@ export default {
mdiMagnify, mdiCloseCircle,
isCurrentMonth: true,
now: dayjs().unix(),
date: dayjs.tz().format('YYYY-MM-DD'),
start: dayjs().startOf('month').unix(),
end: null,
searching: false,
tmpEvents: [],
selectedDay: null,
show_recurrent: $store.state.settings.recurrent_event_visible,
storeUnsubscribe: null,
reload_events: 0
}
}
},
head () {
return {
@@ -69,76 +70,77 @@ export default {
}
},
computed: {
...mapState(['settings', 'announcements', 'events']),
...mapState(['settings', 'announcements', 'events', 'filter']),
visibleEvents () {
if (this.searching) {
if (this.filter.query && this.filter.query.length > 2) {
return this.tmpEvents
}
const now = dayjs().unix()
if (this.selectedDay) {
const min = dayjs.tz(this.selectedDay).startOf('day').unix()
const max = dayjs.tz(this.selectedDay).endOf('day').unix()
return this.events.filter(e => (e.start_datetime <= max && (e.end_datetime || e.start_datetime) >= min) && (this.show_recurrent || !e.parentId))
return this.events.filter(e => (e.start_datetime <= max && (e.end_datetime || e.start_datetime) >= min) && (this.filter.show_recurrent || !e.parentId))
} else if (this.isCurrentMonth) {
return this.events.filter(e => ((e.end_datetime ? e.end_datetime > now : e.start_datetime + 3 * 60 * 60 > now) && (this.show_recurrent || !e.parentId)))
return this.events.filter(e => ((e.end_datetime ? e.end_datetime > now : e.start_datetime + 3 * 60 * 60 > now) && (this.filter.show_recurrent || !e.parentId)))
} else {
return this.events.filter(e => this.show_recurrent || !e.parentId)
return this.events.filter(e => this.filter.show_recurrent || !e.parentId)
}
}
},
created () {
this.$root.$on('dayclick', this.dayChange)
this.$root.$on('monthchange', this.monthChange)
this.$root.$on('search', debounce(this.search, 100))
this.$root.$on('layout_loaded', () => {
this.reload_events++
})
this.storeUnsubscribe = this.$store.subscribeAction( { after: (action, state) => {
if (action.type === 'setFilter') {
if (this.filter.query && this.filter.query.length > 2) {
this.search()
} else {
this.tmpEvents = []
this.$fetch()
}
}
}})
// this.$root.$on('search', debounce(this.search, 100))
// this.$root.$on('layout_loaded', () => {
// this.reload_events++
// })
},
destroyed () {
this.$root.$off('dayclick')
this.$root.$off('monthchange')
this.$root.$off('search')
if (typeof this.storeUnsubscribe === 'function') {
this.storeUnsubscribe()
}
},
methods: {
...mapActions(['getEvents']),
async search (query) {
if (query) {
this.tmpEvents = await this.$axios.$get(`/event/search?search=${query}`)
this.searching = true
} else {
this.tmpEvents = null
this.searching = false
}
},
updateEvents () {
return this.getEvents({
start: this.start,
end: this.end,
show_recurrent: true
search: debounce(async function() {
this.tmpEvents = await this.$api.getEvents({
start: 0,
show_recurrent: this.filter.show_recurrent,
show_multidate: this.filter.show_multidate,
query: this.filter.query
})
},
}, 200),
async monthChange ({ year, month }) {
this.$nuxt.$loading.start()
this.$nextTick( async () => {
let isCurrentMonth
// unselect current selected day
this.selectedDay = null
// unselect current selected day
this.selectedDay = null
// check if current month is selected
if (month - 1 === dayjs.tz().month() && year === dayjs.tz().year()) {
this.isCurrentMonth = true
this.start = dayjs().startOf('month').unix()
this.date = dayjs.tz().format('YYYY-MM-DD')
} else {
this.isCurrentMonth = false
this.date = ''
this.start = dayjs().year(year).month(month - 1).startOf('month').unix() // .startOf('week').unix()
}
this.end = dayjs().year(year).month(month).endOf('month').unix() // .endOf('week').unix()
await this.updateEvents()
this.$nuxt.$loading.finish()
})
// check if current month is selected
if (month - 1 === dayjs.tz().month() && year === dayjs.tz().year()) {
isCurrentMonth = true
this.start = dayjs().startOf('month').unix()
} else {
isCurrentMonth = false
this.start = dayjs().year(year).month(month - 1).startOf('month').unix() // .startOf('week').unix()
}
this.end = dayjs().year(year).month(month).endOf('month').unix() // .endOf('week').unix()
await this.$fetch()
this.$nuxt.$loading.finish()
this.$nextTick( () => this.isCurrentMonth = isCurrentMonth)
},
dayChange (day) {

View File

@@ -32,7 +32,7 @@ export default {
async asyncData ({ $axios, params, error }) {
try {
const tag = params.tag
const events = await $axios.$get(`/tag/${tag}`)
const events = await $axios.$get(`/tag/${encodeURIComponent(tag)}`)
return { events, tag }
} catch (e) {
error({ statusCode: 400, message: 'Error!' })