mirror of
https://git.joinfirefish.org/firefish/firefish.git
synced 2024-05-19 17:11:12 +02:00
834671839f
Co-authored-by: Kainoa Kanter <kainoa@t1c.dev>
362 lines
8.4 KiB
Vue
362 lines
8.4 KiB
Vue
<template>
|
|
<div class="zmdxowut">
|
|
<MkInput v-model="title" small type="text" class="input">
|
|
<template #label>*{{ i18n.ts._event.title }}</template>
|
|
</MkInput>
|
|
<section>
|
|
<div>
|
|
<section>
|
|
<MkInput
|
|
v-model="startDate"
|
|
small
|
|
type="date"
|
|
class="input"
|
|
>
|
|
<template #label
|
|
>*{{ i18n.ts._event.startDate }}</template
|
|
>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput
|
|
v-model="startTime"
|
|
small
|
|
type="time"
|
|
class="input"
|
|
>
|
|
<template #label
|
|
>*{{ i18n.ts._event.startTime }}</template
|
|
>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="endDate" small type="date" class="input">
|
|
<template #label>{{ i18n.ts._event.endDate }}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="endTime" small type="time" class="input">
|
|
<template #label>{{ i18n.ts._event.endTime }}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="location" small type="text" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.location
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="url" small type="url" class="input">
|
|
<template #label>{{ i18n.ts._event.url }}</template>
|
|
</MkInput>
|
|
</section>
|
|
</div>
|
|
<div>
|
|
<section>
|
|
<MkSwitch
|
|
v-model="showAdvanced"
|
|
:disabled="false"
|
|
class="input"
|
|
>{{ i18n.ts.advanced }}</MkSwitch
|
|
>
|
|
</section>
|
|
</div>
|
|
<div v-show="showAdvanced">
|
|
<section>
|
|
<MkInput v-model="doorTime" small type="time" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.doorTime
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput
|
|
v-model="organizer"
|
|
small
|
|
type="text"
|
|
class="input"
|
|
>
|
|
<template #label>{{
|
|
i18n.ts._event.organizer
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput
|
|
v-model="organizerLink"
|
|
small
|
|
type="url"
|
|
class="input"
|
|
>
|
|
<template #label>{{
|
|
i18n.ts._event.organizerLink
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="audience" small type="text" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.audience
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="language" small type="text" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.language
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="ageRange" small type="text" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.ageRange
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<!--<section>
|
|
<MkInput v-model="performers" small type="text" class="input">
|
|
<template #label>{{ i18n.ts._event.performers }}</template>
|
|
</MkInput>
|
|
</section>-->
|
|
<section>
|
|
<MkInput
|
|
v-model="ticketsUrl"
|
|
small
|
|
type="url"
|
|
class="input"
|
|
>
|
|
<template #label>{{
|
|
i18n.ts._event.ticketsUrl
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkSwitch v-model="isFree" :disabled="false">
|
|
{{ i18n.ts._event.isFree }}
|
|
</MkSwitch>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="price" small type="text" class="input">
|
|
<template #label>{{ i18n.ts._event.price }}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput
|
|
v-model="availabilityStart"
|
|
small
|
|
type="datetime-local"
|
|
class="input"
|
|
>
|
|
<template #label>{{
|
|
i18n.ts._event.availabilityStart
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput
|
|
v-model="availabilityEnd"
|
|
small
|
|
type="datetime-local"
|
|
class="input"
|
|
>
|
|
<template #label>{{
|
|
i18n.ts._event.availabilityEnd
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
<section>
|
|
<MkInput v-model="keywords" small type="text" class="input">
|
|
<template #label>{{
|
|
i18n.ts._event.keywords
|
|
}}</template>
|
|
</MkInput>
|
|
</section>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import * as misskey from "calckey-js";
|
|
import { Ref, ref, watch } from "vue";
|
|
import MkInput from "./MkInput.vue";
|
|
import MkSwitch from "./MkSwitch.vue";
|
|
import { formatDateTimeString } from "@/scripts/format-time-string";
|
|
import { addTime } from "@/scripts/time";
|
|
import { i18n } from "@/i18n";
|
|
const props = defineProps<{
|
|
modelValue: misskey.entities.Note["event"];
|
|
}>();
|
|
const emit = defineEmits<{
|
|
(
|
|
ev: "update:modelValue",
|
|
v: {
|
|
model: misskey.entities.Note["event"];
|
|
}
|
|
);
|
|
}>();
|
|
const title = ref(props.modelValue?.title ?? null);
|
|
const startDate = ref(
|
|
formatDateTimeString(addTime(new Date(), 1, "day"), "yyyy-MM-dd")
|
|
);
|
|
const startTime = ref("00:00");
|
|
const endDate = ref("");
|
|
const endTime = ref("");
|
|
const location = ref(props.modelValue?.metadata.location ?? null);
|
|
const url = ref(props.modelValue?.metadata.url ?? null);
|
|
const showAdvanced = ref(false);
|
|
const doorTime = ref(props.modelValue?.metadata.doorTime ?? null);
|
|
const organizer = ref(props.modelValue?.metadata.organizer?.name ?? null);
|
|
const organizerLink = ref(props.modelValue?.metadata.organizer?.sameAs ?? null);
|
|
const audience = ref(props.modelValue?.metadata.audience?.name ?? null);
|
|
const language = ref(props.modelValue?.metadata.inLanguage ?? null);
|
|
const ageRange = ref(props.modelValue?.metadata.typicalAgeRange ?? null);
|
|
const ticketsUrl = ref(props.modelValue?.metadata.offers?.url ?? null);
|
|
const isFree = ref(props.modelValue?.metadata.isAccessibleForFree ?? false);
|
|
const price = ref(props.modelValue?.metadata.offers?.price ?? null);
|
|
const availabilityStart = ref(
|
|
props.modelValue?.metadata.offers?.availabilityStarts ?? null
|
|
);
|
|
const availabilityEnd = ref(
|
|
props.modelValue?.metadata.offers?.availabilityEnds ?? null
|
|
);
|
|
const keywords = ref(props.modelValue?.metadata.keywords ?? null);
|
|
function get(): misskey.entities.Note["event"] {
|
|
const calcAt = (date: Ref<string>, time: Ref<string>): number =>
|
|
new Date(`${date.value} ${time.value}`).getTime();
|
|
const start = calcAt(startDate, startTime);
|
|
const end = endDate.value ? calcAt(endDate, endTime) : null;
|
|
return {
|
|
title: title.value,
|
|
start: start,
|
|
end: end,
|
|
metadata: {
|
|
"@type": "Event",
|
|
name: title.value,
|
|
startDate: new Date(start).toISOString(),
|
|
endDate: end ? new Date(end).toISOString() : undefined,
|
|
location: location.value ?? undefined,
|
|
url: url.value ?? undefined,
|
|
doorTime: doorTime.value ?? undefined,
|
|
organizer: organizer.value
|
|
? {
|
|
"@type": "Thing",
|
|
name: organizer.value,
|
|
sameAs: organizerLink.value ?? undefined,
|
|
}
|
|
: undefined,
|
|
audience: audience.value
|
|
? {
|
|
"@type": "Audience",
|
|
name: audience.value,
|
|
}
|
|
: undefined,
|
|
inLanguage: language.value ?? undefined,
|
|
typicalAgeRange: ageRange.value ?? undefined,
|
|
isAccessibleForFree: isFree,
|
|
offers:
|
|
ticketsUrl.value || price.value
|
|
? {
|
|
price: price.value ?? undefined,
|
|
priceCurrency: undefined,
|
|
availabilityStarts:
|
|
availabilityStart.value ?? undefined,
|
|
availabilityEnds:
|
|
availabilityEnd.value ?? undefined,
|
|
url: ticketsUrl.value ?? undefined,
|
|
}
|
|
: undefined,
|
|
keywords: keywords.value ?? undefined,
|
|
},
|
|
};
|
|
}
|
|
watch(
|
|
[
|
|
title,
|
|
startDate,
|
|
startTime,
|
|
endDate,
|
|
endTime,
|
|
location,
|
|
url,
|
|
doorTime,
|
|
organizer,
|
|
organizerLink,
|
|
audience,
|
|
language,
|
|
ageRange,
|
|
ticketsUrl,
|
|
isFree,
|
|
price,
|
|
availabilityStart,
|
|
availabilityEnd,
|
|
keywords,
|
|
],
|
|
() => emit("update:modelValue", get()),
|
|
{
|
|
deep: true,
|
|
}
|
|
);
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.zmdxowut {
|
|
padding: 8px 16px;
|
|
> .caution {
|
|
margin: 0 0 8px 0;
|
|
font-size: 0.8em;
|
|
color: var(--warn);
|
|
> i {
|
|
margin-right: 4px;
|
|
}
|
|
}
|
|
> ul {
|
|
display: block;
|
|
margin: 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
> li {
|
|
display: flex;
|
|
margin: 8px 0;
|
|
padding: 0;
|
|
width: 100%;
|
|
> .input {
|
|
flex: 1;
|
|
}
|
|
> button {
|
|
width: 32px;
|
|
padding: 4px 0;
|
|
}
|
|
}
|
|
}
|
|
> section {
|
|
margin: 16px 0 0 0;
|
|
> div {
|
|
margin: 0 8px;
|
|
display: flex;
|
|
flex-direction: row;
|
|
flex-wrap: wrap;
|
|
gap: 12px;
|
|
&:last-child {
|
|
flex: 1 0 auto;
|
|
> div {
|
|
flex-grow: 1;
|
|
}
|
|
> section {
|
|
// MAGIC: Prevent div above from growing unless wrapped to its own line
|
|
flex-grow: 9999;
|
|
align-items: end;
|
|
display: flex;
|
|
gap: 4px;
|
|
> .input {
|
|
flex: 1 1 auto;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|