Merge branch 'main' into '1481-trying-to-contact-the-organizer-contact-crashes-the-app'
# Conflicts: # package.json
This commit is contained in:
@@ -22,7 +22,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { computed, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
const { locale } = useI18n({ useScope: "global" });
|
||||
|
||||
const localeConverted = locale.replace("_", "-");
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -35,15 +40,15 @@ const props = withDefaults(
|
||||
const dateObj = computed<Date>(() => new Date(props.date));
|
||||
|
||||
const month = computed<string>(() =>
|
||||
dateObj.value.toLocaleString(undefined, { month: "short" })
|
||||
dateObj.value.toLocaleString(localeConverted, { month: "short" })
|
||||
);
|
||||
|
||||
const day = computed<string>(() =>
|
||||
dateObj.value.toLocaleString(undefined, { day: "numeric" })
|
||||
dateObj.value.toLocaleString(localeConverted, { day: "numeric" })
|
||||
);
|
||||
|
||||
const weekday = computed<string>(() =>
|
||||
dateObj.value.toLocaleString(undefined, { weekday: "short" })
|
||||
dateObj.value.toLocaleString(localeConverted, { weekday: "short" })
|
||||
);
|
||||
|
||||
const smallStyle = computed<string>(() => (props.small ? "1.2" : "2"));
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<div class="flex-1" v-else>
|
||||
{{ `@${selectedActor.preferredUsername}` }}
|
||||
</div>
|
||||
<o-button type="text" @click="isComponentModalActive = true">
|
||||
<o-button @click="isComponentModalActive = true">
|
||||
{{ $t("Change") }}
|
||||
</o-button>
|
||||
</div>
|
||||
|
||||
@@ -13,8 +13,14 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
import Clock from "vue-material-design-icons/ClockTimeTenOutline.vue";
|
||||
|
||||
const { locale } = useI18n({ useScope: "global" });
|
||||
|
||||
const localeConverted = locale.replace("_", "-");
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
date: string;
|
||||
@@ -26,7 +32,7 @@ const props = withDefaults(
|
||||
const dateObj = computed<Date>(() => new Date(props.date));
|
||||
|
||||
const time = computed<string>(() =>
|
||||
dateObj.value.toLocaleTimeString(undefined, {
|
||||
dateObj.value.toLocaleTimeString(localeConverted, {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
</template>
|
||||
<o-taginput
|
||||
:modelValue="tagsStrings"
|
||||
@update:modelValue="updateTags"
|
||||
@remove="remove"
|
||||
@add="add"
|
||||
:data="filteredTags"
|
||||
:allow-autocomplete="true"
|
||||
:allow-new="true"
|
||||
@@ -69,6 +70,8 @@ const id = computed((): string => {
|
||||
|
||||
const { load: fetchTags } = useFetchTags();
|
||||
|
||||
initTagsStringsValue();
|
||||
|
||||
const getFilteredTags = async (newText: string): Promise<void> => {
|
||||
text.value = newText;
|
||||
const res = await fetchTags(
|
||||
@@ -91,11 +94,16 @@ const filteredTags = computed((): ITag[] => {
|
||||
);
|
||||
});
|
||||
|
||||
watch(props.modelValue, (newValue, oldValue) => {
|
||||
if (newValue != oldValue) {
|
||||
tagsStrings.value = propsValue.value.map((tag: ITag) => tag.title);
|
||||
}
|
||||
});
|
||||
// TODO It seems that '@update:modelValue="updateTags"' does not works anymore...
|
||||
// so temporarily call the function updateTags() at remove and add tag event
|
||||
// https://github.com/oruga-ui/oruga/issues/967
|
||||
function remove() {
|
||||
updateTags(tagsStrings.value);
|
||||
}
|
||||
|
||||
function add() {
|
||||
updateTags(tagsStrings.value);
|
||||
}
|
||||
|
||||
const updateTags = (newTagsStrings: string[]) => {
|
||||
const tagEntities = newTagsStrings.map((tag: string | ITag) => {
|
||||
@@ -106,4 +114,34 @@ const updateTags = (newTagsStrings: string[]) => {
|
||||
});
|
||||
emit("update:modelValue", tagEntities);
|
||||
};
|
||||
|
||||
function isArraysEquals(array1: string[], array2: string[]) {
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
if (array1[i] !== array2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function initTagsStringsValue() {
|
||||
// This is useful when tag data is already cached from the API during navigation inside the app
|
||||
tagsStrings.value = propsValue.value.map((tag: ITag) => tag.title);
|
||||
|
||||
// This watch() function is useful when tag data loads directly from the API upon page load
|
||||
watch(propsValue, () => {
|
||||
const newTagsStrings = propsValue.value.map((tag: ITag) => tag.title);
|
||||
|
||||
// Changing tagsStrings.value triggers updateTags(), updateTags() triggers this watch() function again.
|
||||
// To stop the loop, edit tagsStrings.value only if it has changed !
|
||||
if (!isArraysEquals(tagsStrings.value, newTagsStrings)) {
|
||||
tagsStrings.value = newTagsStrings;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -33,16 +33,16 @@
|
||||
"A resource has been created or updated": "Creouse ou actualizouse un recurso",
|
||||
"A short tagline for your instance homepage. Defaults to \"Gather ⋅ Organize ⋅ Mobilize\"": "Un pequeno subtítulo para o inicio da instancia. Por omisión \"Xuntar ⋅ Organizar ⋅ Mobilizar\"",
|
||||
"A twitter account handle to follow for event updates": "Alcume da conta de twitter para seguir actualizacións do evento",
|
||||
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Unha ferramenta amigable, emancipatoria e ética para xuntar, organizr e mobilizar.",
|
||||
"A user-friendly, emancipatory and ethical tool for gathering, organising, and mobilising.": "Unha ferramenta amigábel, emancipadora e ética para xuntar, organizar e mobilizar.",
|
||||
"A validation email was sent to {email}": "Enviouse un correo de validación a {email}",
|
||||
"API": "API",
|
||||
"Abandon editing": "Saír da edición",
|
||||
"About": "Acerca de",
|
||||
"About Mobilizon": "Acerca de Mobilizon",
|
||||
"About": "Sobre",
|
||||
"About Mobilizon": "Sobre Mobilizon",
|
||||
"About anonymous participation": "Acerca da participación anónima",
|
||||
"About instance": "Acerca da instancia",
|
||||
"About this event": "Acerca deste evento",
|
||||
"About this instance": "Acerca desta instancia",
|
||||
"About this event": "Sobre este evento",
|
||||
"About this instance": "Sobre esta instancia",
|
||||
"About {instance}": "Acerca de {instance}",
|
||||
"Accept": "Aceptar",
|
||||
"Accept follow": "Aceptar seguimento",
|
||||
@@ -873,7 +873,7 @@
|
||||
"Please add as many details as possible to help identify the problem.": "Por favor engade tódolos detalles posibles para axudarnos a identificar o problema.",
|
||||
"Please check your spam folder if you didn't receive the email.": "Comproba o cartafol de spam se non recibiches o correo.",
|
||||
"Please contact this instance's Mobilizon admin if you think this is a mistake.": "Contacta coa administración da instancia Mobilizon se cres que é un erro.",
|
||||
"Please do not use it in any real way.": "Non o utilices para eventos reais.",
|
||||
"Please do not use it in any real way.": "Non o utilice para eventos reais.",
|
||||
"Please enter your password to confirm this action.": "Escribe o teu contrasinal para confirmar a acción.",
|
||||
"Please make sure the address is correct and that the page hasn't been moved.": "Comproba ben o enderezo e que a páxina non foi movida a outro lugar.",
|
||||
"Please read the {fullRules} published by {instance}'s administrators.": "Por favor le as {fullRules} publicadas pola administración de {instance}.",
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"Access group memberships": "Pristupi članstvima grupa",
|
||||
"Access group suggested events": "Pristupi predloženim grupnim događajima",
|
||||
"Access group todo-lists": "Pristupi popisu grupnih zadataka",
|
||||
"Access group todo-lists": "Pristupi popisu zadataka grupe",
|
||||
"Access organized events": "Pristupi organiziranim događajima",
|
||||
"Access participations": "Pristupi sudjelovanjima",
|
||||
"Access your group's resources": "Pristupi resursima tvoje grupe",
|
||||
|
||||
420
src/i18n/nl.json
420
src/i18n/nl.json
File diff suppressed because it is too large
Load Diff
@@ -271,6 +271,7 @@
|
||||
>
|
||||
<template #default>
|
||||
<event-map
|
||||
v-if="showMap"
|
||||
:routingType="routingType ?? RoutingType.OPENSTREETMAP"
|
||||
:address="event.physicalAddress"
|
||||
@close="showMap = false"
|
||||
|
||||
@@ -23,10 +23,27 @@
|
||||
<div
|
||||
class="rounded p-3 flex-auto md:flex-none bg-zinc-300 dark:bg-zinc-700"
|
||||
>
|
||||
<o-field>
|
||||
<o-switch v-model="showUpcoming">{{
|
||||
showUpcoming ? t("Upcoming events") : t("Past events")
|
||||
}}</o-switch>
|
||||
<o-field
|
||||
class="date-filter"
|
||||
expanded
|
||||
:label="
|
||||
showUpcoming
|
||||
? t('Showing events starting on')
|
||||
: t('Showing events before')
|
||||
"
|
||||
labelFor="events-start-datepicker"
|
||||
>
|
||||
<o-datepicker
|
||||
v-model="datePick"
|
||||
:first-day-of-week="firstDayOfWeek"
|
||||
id="events-start-datepicker"
|
||||
/>
|
||||
<o-button
|
||||
@click="datePick = new Date()"
|
||||
class="reset-area !h-auto"
|
||||
icon-left="close"
|
||||
:title="t('Clear date filter field')"
|
||||
/>
|
||||
</o-field>
|
||||
<o-field v-if="showUpcoming">
|
||||
<o-checkbox v-model="showDrafts">{{ t("Drafts") }}</o-checkbox>
|
||||
@@ -50,28 +67,6 @@
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<o-field
|
||||
class="date-filter"
|
||||
expanded
|
||||
:label="
|
||||
showUpcoming
|
||||
? t('Showing events starting on')
|
||||
: t('Showing events before')
|
||||
"
|
||||
labelFor="events-start-datepicker"
|
||||
>
|
||||
<o-datepicker
|
||||
v-model="dateFilter"
|
||||
:first-day-of-week="firstDayOfWeek"
|
||||
id="events-start-datepicker"
|
||||
/>
|
||||
<o-button
|
||||
@click="dateFilter = new Date()"
|
||||
class="reset-area !h-auto"
|
||||
icon-left="close"
|
||||
:title="t('Clear date filter field')"
|
||||
/>
|
||||
</o-field>
|
||||
</div>
|
||||
<div class="flex-1 min-w-[300px]">
|
||||
<section
|
||||
@@ -250,27 +245,43 @@ const futurePage = ref(1);
|
||||
const pastPage = ref(1);
|
||||
const limit = ref(10);
|
||||
|
||||
function startOfDay(d: Date): string {
|
||||
const pad = (n: int): string => {
|
||||
return (n > 9 ? "" : "0") + n.toString();
|
||||
};
|
||||
return (
|
||||
d.getFullYear() +
|
||||
"-" +
|
||||
pad(d.getMonth() + 1) +
|
||||
"-" +
|
||||
pad(d.getDate()) +
|
||||
"T00:00:00Z"
|
||||
);
|
||||
}
|
||||
|
||||
const showUpcoming = useRouteQuery("showUpcoming", true, booleanTransformer);
|
||||
const showDrafts = useRouteQuery("showDrafts", true, booleanTransformer);
|
||||
const showAttending = useRouteQuery("showAttending", true, booleanTransformer);
|
||||
const showMyGroups = useRouteQuery("showMyGroups", false, booleanTransformer);
|
||||
const dateFilter = useRouteQuery("dateFilter", new Date(), {
|
||||
const dateFilter = useRouteQuery("dateFilter", startOfDay(new Date()), {
|
||||
fromQuery(query) {
|
||||
if (query && /(\d{4}-\d{2}-\d{2})/.test(query)) {
|
||||
return new Date(`${query}T00:00:00Z`);
|
||||
return `${query}T00:00:00Z`;
|
||||
}
|
||||
return new Date();
|
||||
return startOfDay(new Date());
|
||||
},
|
||||
toQuery(value: Date) {
|
||||
const pad = (number: number) => {
|
||||
if (number < 10) {
|
||||
return "0" + number;
|
||||
}
|
||||
return number;
|
||||
};
|
||||
return `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(
|
||||
value.getDate()
|
||||
)}`;
|
||||
toQuery(value: string) {
|
||||
return value.slice(0, 10);
|
||||
},
|
||||
});
|
||||
|
||||
// bridge between datepicker expecting a Date object and dateFilter being a string
|
||||
const datePick = computed({
|
||||
get: () => {
|
||||
return new Date(dateFilter.value);
|
||||
},
|
||||
set: (d: Date) => {
|
||||
dateFilter.value = startOfDay(d);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -323,10 +334,7 @@ const pastParticipations = computed(
|
||||
}
|
||||
);
|
||||
|
||||
const monthlyEvents = (
|
||||
elements: Eventable[],
|
||||
revertSort = false
|
||||
): Map<string, Eventable[]> => {
|
||||
const monthlyEvents = (elements: Eventable[]): Map<string, Eventable[]> => {
|
||||
const res = elements.filter((element: Eventable) => {
|
||||
if ("role" in element) {
|
||||
return (
|
||||
@@ -336,19 +344,12 @@ const monthlyEvents = (
|
||||
}
|
||||
return element.beginsOn != null;
|
||||
});
|
||||
if (revertSort) {
|
||||
res.sort((a: Eventable, b: Eventable) => {
|
||||
const aTime = "role" in a ? a.event.beginsOn : a.beginsOn;
|
||||
const bTime = "role" in b ? b.event.beginsOn : b.beginsOn;
|
||||
return new Date(bTime).getTime() - new Date(aTime).getTime();
|
||||
});
|
||||
} else {
|
||||
res.sort((a: Eventable, b: Eventable) => {
|
||||
const aTime = "role" in a ? a.event.beginsOn : a.beginsOn;
|
||||
const bTime = "role" in b ? b.event.beginsOn : b.beginsOn;
|
||||
return new Date(aTime).getTime() - new Date(bTime).getTime();
|
||||
});
|
||||
}
|
||||
// sort by start date, ascending
|
||||
res.sort((a: Eventable, b: Eventable) => {
|
||||
const aTime = "role" in a ? a.event.beginsOn : a.beginsOn;
|
||||
const bTime = "role" in b ? b.event.beginsOn : b.beginsOn;
|
||||
return new Date(aTime).getTime() - new Date(bTime).getTime();
|
||||
});
|
||||
return res.reduce((acc: Map<string, Eventable[]>, element: Eventable) => {
|
||||
const month = new Date(
|
||||
"role" in element ? element.event.beginsOn : element.beginsOn
|
||||
|
||||
@@ -195,6 +195,10 @@ onMounted(async () => {
|
||||
pictureFile.value = await buildFileFromIMedia(post.value?.picture);
|
||||
});
|
||||
|
||||
// This is useful when post data is already cached from the API during navigation inside the app
|
||||
editablePost.value = { ...editablePost.value, ...post.value };
|
||||
|
||||
// This watch() function is useful when post data loads directly from the API upon page load
|
||||
watch(post, async (newPost: IPost | undefined, oldPost: IPost | undefined) => {
|
||||
if (oldPost?.picture !== newPost?.picture) {
|
||||
pictureFile.value = await buildFileFromIMedia(post.value?.picture);
|
||||
|
||||
Reference in New Issue
Block a user