Fix lint issues, update deps
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
86ca52c2cb
commit
151a7e54ae
@ -1,2 +1,2 @@
|
||||
elixir 1.13.4-otp-25
|
||||
erlang 25.0.3
|
||||
elixir 1.14.0-otp-25
|
||||
erlang 25.0.4
|
||||
|
@ -1,7 +1,7 @@
|
||||
FROM elixir:latest
|
||||
LABEL maintainer="Thomas Citharel <tcit@tcit.fr>"
|
||||
|
||||
ENV REFRESHED_AT=2022-04-06
|
||||
ENV REFRESHED_AT=2022-09-20
|
||||
RUN apt-get update -yq && apt-get install -yq build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 cmake exiftool python3-pip python3-setuptools
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash && apt-get install nodejs -yq
|
||||
RUN npm install -g yarn wait-on
|
||||
|
@ -53,4 +53,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
ignorePatterns: ["src/typings/*.d.ts", "vue.config.js"],
|
||||
globals: {
|
||||
GeolocationPositionError: true,
|
||||
},
|
||||
};
|
||||
|
@ -45,6 +45,7 @@
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.26",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-underline": "^2.0.0-beta.7",
|
||||
"@tiptap/suggestion": "^2.0.0-beta.195",
|
||||
"@tiptap/vue-3": "^2.0.0-beta.96",
|
||||
"@vue-a11y/announcer": "^2.1.0",
|
||||
"@vue-a11y/skip-to": "^2.1.2",
|
||||
@ -54,10 +55,9 @@
|
||||
"@vueuse/core": "^9.1.0",
|
||||
"@vueuse/head": "^0.7.9",
|
||||
"@vueuse/router": "^9.0.2",
|
||||
"@xiaoshuapp/draggable": "^4.1.0",
|
||||
"apollo-absinthe-upload-link": "^1.5.0",
|
||||
"autoprefixer": "^10",
|
||||
"blurhash": "^1.1.3",
|
||||
"blurhash": "^2.0.0",
|
||||
"bulma": "^0.9.4",
|
||||
"bulma-divider": "^0.2.0",
|
||||
"date-fns": "^2.16.0",
|
||||
@ -82,16 +82,15 @@
|
||||
"tippy.js": "^6.2.3",
|
||||
"unfetch": "^4.2.0",
|
||||
"vue": "^3.2.37",
|
||||
"vue-class-component": "8.0.0-rc.1",
|
||||
"vue-i18n": "9",
|
||||
"vue-material-design-icons": "^5.1.2",
|
||||
"vue-matomo": "^4.1.0",
|
||||
"vue-meta": "^2.3.1",
|
||||
"vue-plausible": "^1.3.1",
|
||||
"vue-property-decorator": "10.0.0-rc.3",
|
||||
"vue-router": "4",
|
||||
"vue-scrollto": "^2.17.1",
|
||||
"vue-use-route-query": "^1.1.0"
|
||||
"vue-use-route-query": "^1.1.0",
|
||||
"vuedraggable": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@histoire/plugin-vue": "^0.10.0",
|
||||
@ -113,7 +112,7 @@
|
||||
"@types/prosemirror-view": "^1.11.4",
|
||||
"@types/sanitize-html": "^2.5.0",
|
||||
"@vitejs/plugin-vue": "^3.0.3",
|
||||
"@vitest/ui": "^0.22.1",
|
||||
"@vitest/ui": "^0.23.4",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.0.2",
|
||||
@ -130,10 +129,10 @@
|
||||
"prettier-eslint": "^15.0.1",
|
||||
"rollup-plugin-visualizer": "^5.7.1",
|
||||
"sass": "^1.34.1",
|
||||
"typescript": "~4.7.4",
|
||||
"typescript": "~4.8.3",
|
||||
"vite": "^3.0.9",
|
||||
"vite-plugin-pwa": "^0.12.3",
|
||||
"vitest": "^0.22.1",
|
||||
"vite-plugin-pwa": "^0.13.0",
|
||||
"vitest": "^0.23.3",
|
||||
"vue-i18n-extract": "^2.0.4"
|
||||
}
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ body {
|
||||
/* Modal */
|
||||
|
||||
.modal-content {
|
||||
@apply bg-white dark:bg-zinc-800 rounded px-2 py-4 w-full;
|
||||
@apply bg-white dark:bg-zinc-800 rounded px-2 py-4 w-full z-0;
|
||||
}
|
||||
|
||||
/* Switch */
|
||||
@ -210,7 +210,7 @@ button.menubar__button {
|
||||
|
||||
/* Table */
|
||||
.table tr {
|
||||
@apply odd:bg-white dark:odd:bg-zinc-600 even:bg-gray-50 dark:even:bg-zinc-700 border-b rounded;
|
||||
@apply odd:bg-white dark:odd:bg-zinc-600 last:border-b-0 even:bg-gray-50 dark:even:bg-zinc-700 border-b rounded;
|
||||
}
|
||||
|
||||
.table-td {
|
||||
|
@ -8,6 +8,5 @@
|
||||
border: 2px solid;
|
||||
z-index: 2;
|
||||
flex-shrink: 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -62,9 +62,10 @@ const mentionOptions: MentionOptions = {
|
||||
let popup: any;
|
||||
|
||||
return {
|
||||
onStart: (props: any) => {
|
||||
onStart: (props: Record<string, any>) => {
|
||||
component = new VueRenderer(MentionList, {
|
||||
propsData: props,
|
||||
props,
|
||||
editor: props.editor,
|
||||
});
|
||||
|
||||
popup = tippy("body", {
|
||||
|
@ -20,7 +20,7 @@ import { ref, watch } from "vue";
|
||||
|
||||
const props = defineProps<{
|
||||
items: IPerson[];
|
||||
command: ({ id }: { id: string }) => {};
|
||||
command: ({ id }: { id: string }) => any;
|
||||
}>();
|
||||
|
||||
// @Prop({ type: Function, required: true }) command!: any;
|
||||
@ -31,37 +31,37 @@ watch(props.items, () => {
|
||||
selectedIndex.value = 0;
|
||||
});
|
||||
|
||||
const onKeyDown = ({ event }: { event: KeyboardEvent }): boolean => {
|
||||
if (event.key === "ArrowUp") {
|
||||
upHandler();
|
||||
return true;
|
||||
}
|
||||
// const onKeyDown = ({ event }: { event: KeyboardEvent }): boolean => {
|
||||
// if (event.key === "ArrowUp") {
|
||||
// upHandler();
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (event.key === "ArrowDown") {
|
||||
downHandler();
|
||||
return true;
|
||||
}
|
||||
// if (event.key === "ArrowDown") {
|
||||
// downHandler();
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (event.key === "Enter") {
|
||||
enterHandler();
|
||||
return true;
|
||||
}
|
||||
// if (event.key === "Enter") {
|
||||
// enterHandler();
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
};
|
||||
// return false;
|
||||
// };
|
||||
|
||||
const upHandler = (): void => {
|
||||
selectedIndex.value =
|
||||
(selectedIndex.value + props.items.length - 1) % props.items.length;
|
||||
};
|
||||
// const upHandler = (): void => {
|
||||
// selectedIndex.value =
|
||||
// (selectedIndex.value + props.items.length - 1) % props.items.length;
|
||||
// };
|
||||
|
||||
const downHandler = (): void => {
|
||||
selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
|
||||
};
|
||||
// const downHandler = (): void => {
|
||||
// selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
|
||||
// };
|
||||
|
||||
const enterHandler = (): void => {
|
||||
selectItem(selectedIndex.value);
|
||||
};
|
||||
// const enterHandler = (): void => {
|
||||
// selectItem(selectedIndex.value);
|
||||
// };
|
||||
|
||||
const selectItem = (index: number): void => {
|
||||
const item = props.items[index];
|
||||
|
@ -1,149 +0,0 @@
|
||||
<template>
|
||||
<div class="address-autocomplete">
|
||||
<!-- <o-field expanded>
|
||||
<o-autocomplete
|
||||
:data="addressData"
|
||||
v-model="queryText"
|
||||
:placeholder="$t('e.g. 10 Rue Jangot')"
|
||||
field="fullName"
|
||||
:loading="isFetching"
|
||||
@typing="fetchAsyncData"
|
||||
icon="map-marker"
|
||||
expanded
|
||||
@select="updateSelected"
|
||||
v-bind="$attrs"
|
||||
dir="auto"
|
||||
>
|
||||
<template #default="{ option }">
|
||||
<o-icon :icon="option.poiInfos.poiIcon.icon" />
|
||||
<b>{{ option.poiInfos.name }}</b
|
||||
><br />
|
||||
<small>{{ option.poiInfos.alternativeName }}</small>
|
||||
</template>
|
||||
</o-autocomplete>
|
||||
</o-field>
|
||||
<o-field
|
||||
v-if="canDoGeoLocation"
|
||||
:message="fieldErrors"
|
||||
:type="{ 'is-danger': fieldErrors.length }"
|
||||
>
|
||||
<o-button
|
||||
type="is-text"
|
||||
v-if="!gettingLocation"
|
||||
icon-right="target"
|
||||
@click="locateMe"
|
||||
@keyup.enter="locateMe"
|
||||
>{{ $t("Use my location") }}</o-button
|
||||
>
|
||||
<span v-else>{{ $t("Getting location") }}</span>
|
||||
</o-field> -->
|
||||
<!--
|
||||
<div v-if="selected && selected.geom" class="control">
|
||||
<o-checkbox @input="togglemap" />
|
||||
<label class="label">{{ $t("Show map") }}</label>
|
||||
</div>
|
||||
|
||||
<div class="map" v-if="showmap && selected && selected.geom">
|
||||
<map-leaflet
|
||||
:coords="selected.geom"
|
||||
:marker="{
|
||||
text: [selected.poiInfos.name, selected.poiInfos.alternativeName],
|
||||
icon: selected.poiInfos.poiIcon.icon,
|
||||
}"
|
||||
:updateDraggableMarkerCallback="reverseGeoCode"
|
||||
:options="{ zoom: mapDefaultZoom }"
|
||||
:readOnly="false"
|
||||
/>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Prop, Watch, Vue } from "vue-property-decorator";
|
||||
import { Address, IAddress } from "../../types/address.model";
|
||||
// import AddressAutoCompleteMixin from "@/mixins/AddressAutoCompleteMixin";
|
||||
|
||||
// @Component({
|
||||
// inheritAttrs: false,
|
||||
// })
|
||||
export default class AddressAutoComplete extends Vue {
|
||||
@Prop({ required: false, default: false }) type!: string | false;
|
||||
@Prop({ required: false, default: true, type: Boolean })
|
||||
doGeoLocation!: boolean;
|
||||
|
||||
addressData: IAddress[] = [];
|
||||
|
||||
selected: IAddress = new Address();
|
||||
|
||||
initialQueryText = "";
|
||||
|
||||
addressModalActive = false;
|
||||
|
||||
showmap = false;
|
||||
|
||||
get queryText2(): string {
|
||||
if (this.value !== undefined) {
|
||||
return new Address(this.value).fullName;
|
||||
}
|
||||
return this.initialQueryText;
|
||||
}
|
||||
|
||||
set queryText2(queryText: string) {
|
||||
this.initialQueryText = queryText;
|
||||
}
|
||||
|
||||
@Watch("value")
|
||||
updateEditing(): void {
|
||||
if (!this.value?.id) return;
|
||||
this.selected = this.value;
|
||||
}
|
||||
|
||||
updateSelected(option: IAddress): void {
|
||||
if (option == null) return;
|
||||
this.selected = option;
|
||||
// this.$emit("input", this.selected);
|
||||
}
|
||||
|
||||
resetPopup(): void {
|
||||
this.selected = new Address();
|
||||
}
|
||||
|
||||
openNewAddressModal(): void {
|
||||
this.resetPopup();
|
||||
this.addressModalActive = true;
|
||||
}
|
||||
|
||||
togglemap(): void {
|
||||
this.showmap = !this.showmap;
|
||||
}
|
||||
|
||||
get canDoGeoLocation(): boolean {
|
||||
return this.isSecureContext && this.doGeoLocation;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.address-autocomplete {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.autocomplete {
|
||||
.dropdown-menu {
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.dropdown-item.is-disabled {
|
||||
opacity: 1 !important;
|
||||
cursor: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.read-only {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.map {
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -150,7 +150,7 @@ import RouteName from "../../router/name";
|
||||
import InlineAddress from "@/components/Address/InlineAddress.vue";
|
||||
|
||||
import { computed, inject } from "vue";
|
||||
import MobilizonTag from "@/components/Tag.vue";
|
||||
import MobilizonTag from "@/components/TagElement.vue";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Video from "vue-material-design-icons/Video.vue";
|
||||
import { formatDateTimeForEvent } from "@/utils/datetime";
|
||||
|
@ -84,7 +84,7 @@
|
||||
</template>
|
||||
<a
|
||||
target="_blank"
|
||||
class="hover:underline"
|
||||
class="underline"
|
||||
rel="noopener noreferrer ugc"
|
||||
:href="event.onlineAddress"
|
||||
:title="
|
||||
|
@ -130,7 +130,7 @@ import InlineAddress from "@/components/Address/InlineAddress.vue";
|
||||
import Video from "vue-material-design-icons/Video.vue";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import AccountMultiple from "vue-material-design-icons/AccountMultiple.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
|
@ -301,7 +301,7 @@ import {
|
||||
organizerAvatarUrl,
|
||||
organizerDisplayName,
|
||||
} from "@/types/event.model";
|
||||
import { displayNameAndUsername, IActor, IPerson } from "@/types/actor";
|
||||
import { displayNameAndUsername, IPerson } from "@/types/actor";
|
||||
import { CURRENT_ACTOR_CLIENT } from "@/graphql/actor";
|
||||
import RouteName from "@/router/name";
|
||||
import { changeIdentity } from "@/utils/identity";
|
||||
@ -323,29 +323,12 @@ import { useI18n } from "vue-i18n";
|
||||
import { Dialog } from "@/plugins/dialog";
|
||||
import { Snackbar } from "@/plugins/snackbar";
|
||||
import { useDeleteEvent } from "@/composition/apollo/event";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const defaultOptions: IEventCardOptions = {
|
||||
hideDate: true,
|
||||
loggedPerson: false,
|
||||
hideDetails: false,
|
||||
organizerActor: null,
|
||||
};
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
participation: IParticipant;
|
||||
options?: IEventCardOptions;
|
||||
}>(),
|
||||
{
|
||||
options: () => ({
|
||||
hideDate: true,
|
||||
loggedPerson: false,
|
||||
hideDetails: false,
|
||||
organizerActor: null,
|
||||
}),
|
||||
}
|
||||
);
|
||||
const props = defineProps<{
|
||||
participation: IParticipant;
|
||||
options?: IEventCardOptions;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits(["eventDeleted"]);
|
||||
|
||||
@ -353,10 +336,6 @@ const { result: currentActorResult } = useQuery(CURRENT_ACTOR_CLIENT);
|
||||
const currentActor = computed(() => currentActorResult.value?.currentActor);
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const mergedOptions = computed<IEventCardOptions>(() => {
|
||||
return { ...defaultOptions, ...props.options };
|
||||
});
|
||||
|
||||
const dialog = inject<Dialog>("dialog");
|
||||
|
||||
const openDeleteEventModal = (
|
||||
@ -441,9 +420,8 @@ onDeleteEventError((error) => {
|
||||
* Delete the event
|
||||
*/
|
||||
const openDeleteEventModalWrapper = () => {
|
||||
openDeleteEventModal(
|
||||
props.participation.event,
|
||||
deleteEvent(props.participation.event)
|
||||
openDeleteEventModal(props.participation.event, (event: IEvent) =>
|
||||
deleteEvent({ eventId: event.id ?? "" })
|
||||
);
|
||||
};
|
||||
|
||||
@ -474,15 +452,15 @@ const gotToWithCheck = async (
|
||||
return router.push(route);
|
||||
};
|
||||
|
||||
const organizerActor = computed<IActor | undefined>(() => {
|
||||
if (
|
||||
props.participation.event.attributedTo &&
|
||||
props.participation.event.attributedTo.id
|
||||
) {
|
||||
return props.participation.event.attributedTo;
|
||||
}
|
||||
return props.participation.event.organizerActor;
|
||||
});
|
||||
// const organizerActor = computed<IActor | undefined>(() => {
|
||||
// if (
|
||||
// props.participation.event.attributedTo &&
|
||||
// props.participation.event.attributedTo.id
|
||||
// ) {
|
||||
// return props.participation.event.attributedTo;
|
||||
// }
|
||||
// return props.participation.event.organizerActor;
|
||||
// });
|
||||
|
||||
const seatsLeft = computed<number | null>(() => {
|
||||
if (props.participation.event.options.maximumAttendeeCapacity > 0) {
|
||||
|
@ -143,7 +143,7 @@ const props = withDefaults(
|
||||
}
|
||||
);
|
||||
|
||||
const addressModalActive = ref(false);
|
||||
// const addressModalActive = ref(false);
|
||||
|
||||
const componentId = 0;
|
||||
|
||||
@ -186,14 +186,14 @@ const updateSelected = (option: IAddress): void => {
|
||||
emit("update:modelValue", selected.value);
|
||||
};
|
||||
|
||||
const resetPopup = (): void => {
|
||||
selected.value = new Address();
|
||||
};
|
||||
// const resetPopup = (): void => {
|
||||
// selected.value = new Address();
|
||||
// };
|
||||
|
||||
const openNewAddressModal = (): void => {
|
||||
resetPopup();
|
||||
addressModalActive.value = true;
|
||||
};
|
||||
// const openNewAddressModal = (): void => {
|
||||
// resetPopup();
|
||||
// addressModalActive.value = true;
|
||||
// };
|
||||
|
||||
const checkCurrentPosition = (e: LatLng): boolean => {
|
||||
if (!selected.value?.geom) return false;
|
||||
|
@ -94,7 +94,7 @@ import ExitToApp from "vue-material-design-icons/ExitToApp.vue";
|
||||
import DotsHorizontal from "vue-material-design-icons/DotsHorizontal.vue";
|
||||
import AccountGroup from "vue-material-design-icons/AccountGroup.vue";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import { htmlToText } from "@/utils/html";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
@click="clickMap"
|
||||
@update:zoom="updateZoom"
|
||||
:options="{ zoomControl: false }"
|
||||
ref="mapComponent"
|
||||
@ready="onMapReady"
|
||||
>
|
||||
<l-tile-layer :url="tiles?.endpoint" :attribution="attribution">
|
||||
</l-tile-layer>
|
||||
@ -16,28 +18,36 @@
|
||||
:zoomInTitle="$t('Zoom in')"
|
||||
:zoomOutTitle="$t('Zoom out')"
|
||||
></l-control-zoom>
|
||||
<!-- <v-locatecontrol
|
||||
v-if="canDoGeoLocation"
|
||||
:options="{ icon: 'mdi mdi-map-marker' }"
|
||||
/> -->
|
||||
<l-marker
|
||||
:lat-lng="[lat, lon]"
|
||||
@add="openPopup"
|
||||
@update:latLng="updateDraggableMarkerPosition"
|
||||
:draggable="!readOnly"
|
||||
>
|
||||
<l-popup v-if="popupMultiLine">
|
||||
<l-icon>
|
||||
<MapMarker :size="48" class="text-mbz-purple" />
|
||||
</l-icon>
|
||||
<l-popup v-if="popupMultiLine" :options="{ offset: new Point(22, 8) }">
|
||||
<span v-for="line in popupMultiLine" :key="line"
|
||||
>{{ line }}<br
|
||||
/></span>
|
||||
</l-popup>
|
||||
</l-marker>
|
||||
</l-map>
|
||||
<CrosshairsGps ref="locationIcon" class="hidden" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Icon, LatLng, LeafletMouseEvent, LeafletEvent } from "leaflet";
|
||||
import {
|
||||
LatLng,
|
||||
LeafletMouseEvent,
|
||||
LeafletEvent,
|
||||
Control,
|
||||
DomUtil,
|
||||
Map,
|
||||
Point,
|
||||
} from "leaflet";
|
||||
import "leaflet/dist/leaflet.css";
|
||||
import {
|
||||
LMap,
|
||||
@ -47,10 +57,12 @@ import {
|
||||
LIcon,
|
||||
LControlZoom,
|
||||
} from "@vue-leaflet/vue-leaflet";
|
||||
// import Vue2LeafletLocateControl from "@/components/Map/Vue2LeafletLocateControl.vue";
|
||||
import { computed, nextTick, onMounted, ref } from "vue";
|
||||
import { useMapTiles } from "@/composition/apollo/config";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import Locatecontrol from "leaflet.locatecontrol";
|
||||
import CrosshairsGps from "vue-material-design-icons/CrosshairsGps.vue";
|
||||
import MapMarker from "vue-material-design-icons/MapMarker.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@ -77,8 +89,18 @@ const defaultOptions: {
|
||||
|
||||
const zoom = ref(defaultOptions.zoom);
|
||||
|
||||
onMounted(() => {
|
||||
const mapComponent = ref();
|
||||
const mapObject = ref<Map>();
|
||||
const locateControl = ref<Control.Locate>();
|
||||
const locationIcon = ref();
|
||||
|
||||
const locationIconHTML = computed(() => locationIcon.value?.$el.innerHTML);
|
||||
|
||||
onMounted(async () => {
|
||||
// this part resolve an issue where the markers would not appear
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
// delete Icon.Default.prototype._getIconUrl;
|
||||
// Icon.Default.mergeOptions({
|
||||
// iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"),
|
||||
@ -87,6 +109,50 @@ onMounted(() => {
|
||||
// });
|
||||
});
|
||||
|
||||
const onMapReady = async () => {
|
||||
mapObject.value = mapComponent.value.leafletObject;
|
||||
mountLocateControl();
|
||||
};
|
||||
|
||||
const mountLocateControl = () => {
|
||||
if (canDoGeoLocation.value && mapObject.value) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
locateControl.value = new Locatecontrol({
|
||||
strings: { title: t("Show me where I am") as string },
|
||||
position: "topleft",
|
||||
drawCircle: false,
|
||||
drawMarker: false,
|
||||
createButtonCallback(container: HTMLElement | undefined, options: any) {
|
||||
const link = DomUtil.create(
|
||||
"a",
|
||||
"leaflet-bar-part leaflet-bar-part-single",
|
||||
container
|
||||
);
|
||||
link.title = options.strings.title;
|
||||
link.href = "#";
|
||||
link.setAttribute("role", "button");
|
||||
|
||||
const icon = DomUtil.create(
|
||||
"span",
|
||||
"material-design-icon rss-icon",
|
||||
link
|
||||
);
|
||||
icon.setAttribute("aria-hidden", "true");
|
||||
icon.setAttribute("role", "img");
|
||||
icon.insertAdjacentHTML("beforeend", locationIconHTML.value);
|
||||
console.log("icon for location", {
|
||||
link,
|
||||
icon,
|
||||
});
|
||||
return { link, icon };
|
||||
},
|
||||
...props.options,
|
||||
}) as Control.Locate;
|
||||
locateControl.value?.addTo(mapObject.value);
|
||||
}
|
||||
};
|
||||
|
||||
const openPopup = async (event: LeafletEvent): Promise<void> => {
|
||||
await nextTick();
|
||||
event.target.openPopup();
|
||||
@ -147,3 +213,6 @@ div.map-container {
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
@import "leaflet.locatecontrol/dist/L.Control.Locate.css";
|
||||
</style>
|
||||
|
@ -1,64 +0,0 @@
|
||||
<template>
|
||||
<div style="display: none">
|
||||
<slot v-if="ready"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Fork of https://github.com/domoritz/leaflet-locatecontrol
|
||||
* to try to trigger location manually (not done ATM)
|
||||
*/
|
||||
|
||||
import { DomEvent } from "leaflet";
|
||||
// import { findRealParent, propsBinder } from "vue2-leaflet";
|
||||
import Locatecontrol from "leaflet.locatecontrol";
|
||||
import { Component, Prop, Vue } from "vue-property-decorator";
|
||||
|
||||
@Component({
|
||||
beforeDestroy() {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
this.parentContainer.removeLayer(this);
|
||||
},
|
||||
})
|
||||
export default class Vue2LeafletLocateControl extends Vue {
|
||||
@Prop({ type: Object, default: () => ({}) }) options!: Record<
|
||||
string,
|
||||
unknown
|
||||
>;
|
||||
|
||||
@Prop({ type: Boolean, default: true }) visible!: boolean;
|
||||
|
||||
ready = false;
|
||||
|
||||
mapObject!: any;
|
||||
|
||||
parentContainer: any;
|
||||
|
||||
mounted(): void {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
this.mapObject = new Locatecontrol({
|
||||
...this.options,
|
||||
strings: { title: this.$t("Show me where I am") as string },
|
||||
});
|
||||
DomEvent.on(this.mapObject, this.$listeners as any);
|
||||
propsBinder(this, this.mapObject, this.$props);
|
||||
this.ready = true;
|
||||
this.parentContainer = findRealParent(this.$parent);
|
||||
this.mapObject.addTo(this.parentContainer.mapObject, !this.visible);
|
||||
this.$nextTick(() => {
|
||||
this.$emit("ready", this.mapObject);
|
||||
});
|
||||
}
|
||||
|
||||
public locate(): void {
|
||||
this.mapObject.start();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* @import "~leaflet.locatecontrol/dist/L.Control.Locate.css"; */
|
||||
</style>
|
@ -86,6 +86,7 @@ import { IMedia } from "@/types/media.model";
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import Upload from "vue-material-design-icons/Upload.vue";
|
||||
import { formatBytes } from "@/utils/datetime";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
@ -140,14 +141,4 @@ watch(imageSrc, () => {
|
||||
const showImageLoadingError = (): void => {
|
||||
imagePreviewLoadingError.value = true;
|
||||
};
|
||||
|
||||
// https://gist.github.com/zentala/1e6f72438796d74531803cc3833c039c
|
||||
const formatBytes = (bytes: number, decimals?: number): string => {
|
||||
if (bytes == 0) return "0 Bytes";
|
||||
const k = 1024,
|
||||
dm = decimals || 2,
|
||||
sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
|
||||
};
|
||||
</script>
|
||||
|
@ -61,7 +61,7 @@ import { formatDateTimeString } from "@/filters/datetime";
|
||||
import Tag from "vue-material-design-icons/Tag.vue";
|
||||
import AccountEdit from "vue-material-design-icons/AccountEdit.vue";
|
||||
import Clock from "vue-material-design-icons/Clock.vue";
|
||||
import MbzTag from "@/components/Tag.vue";
|
||||
import MbzTag from "@/components/TagElement.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -22,12 +22,17 @@
|
||||
</div>
|
||||
<div class="">
|
||||
<div class="" v-if="comment">
|
||||
<article class="media">
|
||||
<div class="media-left">
|
||||
<figure class="image is-48x48" v-if="comment?.actor?.avatar">
|
||||
<img :src="comment.actor.avatar.url" alt="" />
|
||||
<article class="">
|
||||
<div class="">
|
||||
<figure class="h-8 w-8" v-if="comment?.actor?.avatar">
|
||||
<img
|
||||
:src="comment.actor.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
height="48"
|
||||
/>
|
||||
</figure>
|
||||
<o-icon v-else size="large" icon="account-circle" />
|
||||
<AccountCircle v-else :size="48" />
|
||||
</div>
|
||||
<div class="">
|
||||
<div class="prose dark:prose-invert">
|
||||
@ -65,7 +70,7 @@
|
||||
</section>
|
||||
|
||||
<footer class="flex gap-2 py-3">
|
||||
<o-button ref="cancelButton" @click="close">
|
||||
<o-button ref="cancelButton" outlined @click="close">
|
||||
{{ translatedCancelText }}
|
||||
</o-button>
|
||||
<o-button
|
||||
|
@ -75,7 +75,7 @@ import ResourceItem from "@/components/Resource/ResourceItem.vue";
|
||||
import FolderItem from "@/components/Resource/FolderItem.vue";
|
||||
import { ref, watch } from "vue";
|
||||
import { IResource } from "@/types/resource";
|
||||
import Draggable from "@xiaoshuapp/draggable";
|
||||
import Draggable from "vuedraggable";
|
||||
import { IGroup } from "@/types/actor";
|
||||
|
||||
const props = withDefaults(
|
||||
@ -124,13 +124,13 @@ watch(checkedAll, () => {
|
||||
});
|
||||
});
|
||||
|
||||
const deleteResource = (resourceID: string) => {
|
||||
validCheckedResources.value = validCheckedResources.value.filter(
|
||||
(id) => id !== resourceID
|
||||
);
|
||||
delete checkedResources.value[resourceID];
|
||||
emit("delete", resourceID);
|
||||
};
|
||||
// const deleteResource = (resourceID: string) => {
|
||||
// validCheckedResources.value = validCheckedResources.value.filter(
|
||||
// (id) => id !== resourceID
|
||||
// );
|
||||
// delete checkedResources.value[resourceID];
|
||||
// emit("delete", resourceID);
|
||||
// };
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@use "@/styles/_mixins" as *;
|
||||
|
@ -18,7 +18,7 @@
|
||||
formatDateTimeString(resource.updatedAt?.toString())
|
||||
}}</span>
|
||||
</div>
|
||||
<!-- <draggable
|
||||
<draggable
|
||||
v-if="!inline"
|
||||
class="dropzone"
|
||||
v-model="list"
|
||||
@ -26,7 +26,7 @@
|
||||
:sort="false"
|
||||
:group="groupObject"
|
||||
@change="onChange"
|
||||
/> -->
|
||||
/>
|
||||
</router-link>
|
||||
<resource-dropdown
|
||||
class="actions"
|
||||
@ -39,18 +39,18 @@
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from "vue-router";
|
||||
// import Draggable, { ChangeEvent } from "@xiaoshuapp/draggable";
|
||||
// import { SnackbarProgrammatic as Snackbar } from "buefy";
|
||||
import Draggable, { ChangeEvent } from "vuedraggable";
|
||||
import { IResource } from "@/types/resource";
|
||||
import RouteName from "@/router/name";
|
||||
import { IGroup, usernameWithDomain } from "@/types/actor";
|
||||
import ResourceDropdown from "./ResourceDropdown.vue";
|
||||
import { UPDATE_RESOURCE } from "@/graphql/resources";
|
||||
import { ref } from "vue";
|
||||
import { inject, ref } from "vue";
|
||||
import { formatDateTimeString } from "@/filters/datetime";
|
||||
import { useMutation } from "@vue/apollo-composable";
|
||||
import { resourcePathArray } from "@/components/Resource/utils";
|
||||
import Folder from "vue-material-design-icons/Folder.vue";
|
||||
import { Snackbar } from "@/plugins/snackbar";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@ -77,7 +77,7 @@ const groupObject: Record<string, unknown> = {
|
||||
|
||||
const onChange = async (evt: ChangeEvent<IResource>) => {
|
||||
if (evt.added && evt.added.element) {
|
||||
const movedResource = evt.added.element as IResource;
|
||||
// const movedResource = evt.added.element as IResource;
|
||||
moveResource({
|
||||
id: props.resource.id,
|
||||
path: `${props.resource.path}/${props.resource.title}`,
|
||||
@ -100,19 +100,20 @@ onMovedResource(({ data }) => {
|
||||
return router.push({
|
||||
name: RouteName.RESOURCE_FOLDER,
|
||||
params: {
|
||||
path: ResourceMixin.resourcePathArray(props.resource),
|
||||
path: resourcePathArray(props.resource),
|
||||
preferredUsername: props.group.preferredUsername,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
const snackbar = inject<Snackbar>("snackbar");
|
||||
|
||||
onMovedResourceError((e) => {
|
||||
// Snackbar.open({
|
||||
// message: e.message,
|
||||
// variant: "danger",
|
||||
// position: "bottom",
|
||||
// });
|
||||
snackbar?.open({
|
||||
message: e.message,
|
||||
variant: "danger",
|
||||
position: "bottom",
|
||||
});
|
||||
return undefined;
|
||||
});
|
||||
</script>
|
||||
|
@ -60,7 +60,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { IResource, mapServiceTypeToIcon } from "@/types/resource";
|
||||
import ResourceDropdown from "@/components/Resource/ResourceDropdown.vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { computed } from "vue";
|
||||
import { formatDateTimeString } from "@/filters/datetime";
|
||||
import Link from "vue-material-design-icons/Link.vue";
|
||||
|
||||
|
@ -2,13 +2,13 @@
|
||||
<div v-if="loggedUser">
|
||||
<section>
|
||||
<div class="setting-title">
|
||||
<h2>{{ $t("Settings") }}</h2>
|
||||
<h2>{{ t("Settings") }}</h2>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{{ $t("Language") }}</h3>
|
||||
<h3>{{ t("Language") }}</h3>
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
t(
|
||||
"This setting will be used to display the website and send you emails in the correct language."
|
||||
)
|
||||
}}
|
||||
@ -17,7 +17,7 @@
|
||||
<o-select
|
||||
:loading="loading"
|
||||
v-model="locale"
|
||||
:placeholder="$t('Select a language')"
|
||||
:placeholder="t('Select a language')"
|
||||
>
|
||||
<option v-for="(language, lang) in langs" :value="lang" :key="lang">
|
||||
{{ language }}
|
||||
@ -27,15 +27,15 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3>{{ $t("Timezone") }}</h3>
|
||||
<h3>{{ t("Timezone") }}</h3>
|
||||
<p>
|
||||
{{
|
||||
$t(
|
||||
t(
|
||||
"We use your timezone to make sure you get notifications for an event at the correct time."
|
||||
)
|
||||
}}
|
||||
{{
|
||||
$t("Your timezone was detected as {timezone}.", {
|
||||
t("Your timezone was detected as {timezone}.", {
|
||||
timezone,
|
||||
})
|
||||
}}
|
||||
@ -43,7 +43,7 @@
|
||||
variant="danger"
|
||||
v-if="!loading && !supportedTimezone"
|
||||
>
|
||||
{{ $t("Your timezone {timezone} isn't supported.", { timezone }) }}
|
||||
{{ t("Your timezone {timezone} isn't supported.", { timezone }) }}
|
||||
</o-notification>
|
||||
</p>
|
||||
</div>
|
||||
@ -71,14 +71,14 @@ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const { loggedUser } = useUserSettings();
|
||||
|
||||
onMounted(() => {
|
||||
updateLocale(locale.value);
|
||||
updateLocale(locale.value as string);
|
||||
doUpdateSetting({ timezone });
|
||||
});
|
||||
|
||||
watch(locale, () => {
|
||||
if (locale.value) {
|
||||
updateLocale(locale.value);
|
||||
saveLocaleData(locale.value);
|
||||
updateLocale(locale.value as string);
|
||||
saveLocaleData(locale.value as string);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -272,11 +272,11 @@ const isBasicMode = computed((): boolean => {
|
||||
return props.mode === "basic";
|
||||
});
|
||||
|
||||
const insertMention = (obj: { range: any; attrs: any }) => {
|
||||
console.debug("initialize Mention");
|
||||
};
|
||||
// const insertMention = (obj: { range: any; attrs: any }) => {
|
||||
// console.debug("initialize Mention");
|
||||
// };
|
||||
|
||||
const observer = ref<MutationObserver | null>(null);
|
||||
// const observer = ref<MutationObserver | null>(null);
|
||||
|
||||
onMounted(() => {
|
||||
editor.value = new Editor({
|
||||
|
@ -24,14 +24,14 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
// import { SnackbarProgrammatic as Snackbar } from "buefy";
|
||||
import { ITodo } from "../../types/todos";
|
||||
import RouteName from "../../router/name";
|
||||
import { UPDATE_TODO } from "../../graphql/todos";
|
||||
import { computed, ref } from "vue";
|
||||
import { computed, inject, ref } from "vue";
|
||||
import { useMutation } from "@vue/apollo-composable";
|
||||
import Account from "vue-material-design-icons/Account.vue";
|
||||
import { formatDateString } from "@/filters/datetime";
|
||||
import { Snackbar } from "@/plugins/snackbar";
|
||||
|
||||
const props = defineProps<{ todo: ITodo }>();
|
||||
|
||||
@ -41,8 +41,8 @@ const status = computed({
|
||||
get() {
|
||||
return props.todo.status;
|
||||
},
|
||||
set(status: boolean) {
|
||||
updateTodo({ status, id: props.todo.id });
|
||||
set(newStatus: boolean) {
|
||||
updateTodo({ status: newStatus, id: props.todo.id });
|
||||
},
|
||||
});
|
||||
|
||||
@ -52,11 +52,13 @@ onDone(() => {
|
||||
editMode.value = false;
|
||||
});
|
||||
|
||||
const snackbar = inject<Snackbar>("snackbar");
|
||||
|
||||
onError((e) => {
|
||||
// Snackbar.open({
|
||||
// message: e.message,
|
||||
// variant: "danger",
|
||||
// position: "bottom",
|
||||
// });
|
||||
snackbar?.open({
|
||||
message: e.message,
|
||||
variant: "danger",
|
||||
position: "bottom",
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -1,102 +0,0 @@
|
||||
<template>
|
||||
<div v-if="attached && closable" class="tags has-addons">
|
||||
<span class="tag" :class="[variant, size, { rounded }]">
|
||||
<!-- <o-icon
|
||||
v-if="icon"
|
||||
:icon="icon"
|
||||
:size="size"
|
||||
:type="iconType"
|
||||
/> -->
|
||||
<span :class="{ 'has-ellipsis': ellipsis }" @click="click">
|
||||
<slot />
|
||||
</span>
|
||||
</span>
|
||||
<a
|
||||
class="tag"
|
||||
role="button"
|
||||
:aria-label="ariaCloseLabel"
|
||||
:tabindex="tabstop ? 0 : undefined"
|
||||
:disabled="disabled"
|
||||
:class="[
|
||||
size,
|
||||
closeType,
|
||||
{ 'is-rounded': rounded },
|
||||
closeIcon ? 'has-delete-icon' : 'is-delete',
|
||||
]"
|
||||
@click="close"
|
||||
@keyup.delete.prevent="close"
|
||||
>
|
||||
<!-- <o-icon
|
||||
custom-class=""
|
||||
v-if="closeIcon"
|
||||
:icon="closeIcon"
|
||||
:size="size"
|
||||
:type="closeIconType"
|
||||
/> -->
|
||||
</a>
|
||||
</div>
|
||||
<span v-else class="tag" :class="[variant, size, { 'is-rounded': rounded }]">
|
||||
<!-- <o-icon
|
||||
v-if="icon"
|
||||
:icon="icon"
|
||||
:size="size"
|
||||
:type="iconType"
|
||||
/> -->
|
||||
<span :class="{ 'has-ellipsis': ellipsis }" @click="click">
|
||||
<slot />
|
||||
</span>
|
||||
|
||||
<a
|
||||
v-if="closable"
|
||||
role="button"
|
||||
:aria-label="ariaCloseLabel"
|
||||
class="delete is-small"
|
||||
:class="closeType"
|
||||
:disabled="disabled"
|
||||
:tabindex="tabstop ? 0 : undefined"
|
||||
@click="close"
|
||||
@keyup.delete.prevent="close"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
attached?: boolean;
|
||||
closable?: boolean;
|
||||
variant?: string;
|
||||
size?: string;
|
||||
rounded?: boolean;
|
||||
disabled?: boolean;
|
||||
ellipsis?: boolean;
|
||||
tabstop?: boolean;
|
||||
ariaCloseLabel?: string;
|
||||
icon?: string;
|
||||
iconType?: string;
|
||||
closeType?: string;
|
||||
closeIcon?: string;
|
||||
closeIconType?: string;
|
||||
}>(),
|
||||
{
|
||||
tabstop: true,
|
||||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(["close", "click"]);
|
||||
|
||||
/**
|
||||
* Emit close event when delete button is clicked
|
||||
* or delete key is pressed.
|
||||
*/
|
||||
const close = (event: Event) => {
|
||||
if (props.disabled) return;
|
||||
emit("close", event);
|
||||
};
|
||||
/**
|
||||
* Emit click event when tag is clicked.
|
||||
*/
|
||||
const click = (event: Event) => {
|
||||
if (props.disabled) return;
|
||||
emit("click", event);
|
||||
};
|
||||
</script>
|
@ -26,13 +26,12 @@
|
||||
<o-field v-if="hasInput">
|
||||
<o-input
|
||||
v-model="prompt"
|
||||
expanded
|
||||
class="input"
|
||||
ref="input"
|
||||
:class="{ 'is-danger': validationMessage }"
|
||||
v-bind="inputAttrs"
|
||||
@keydown.enter="confirm"
|
||||
/>
|
||||
<p class="help is-danger">{{ validationMessage }}</p>
|
||||
</o-field>
|
||||
</div>
|
||||
</section>
|
||||
@ -83,15 +82,14 @@ const emit = defineEmits(["confirm", "cancel", "close"]);
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
const modalOpened = ref(false);
|
||||
const validationMessage = ref("");
|
||||
// const modalOpened = ref(false);
|
||||
|
||||
const prompt = ref<string>(props.hasInput ? props.inputAttrs?.value ?? "" : "");
|
||||
const input = ref();
|
||||
|
||||
const dialogClass = computed(() => {
|
||||
return [props.size];
|
||||
});
|
||||
// const dialogClass = computed(() => {
|
||||
// return [props.size];
|
||||
// });
|
||||
/**
|
||||
* Icon name (MDI) based on the type.
|
||||
*/
|
||||
@ -114,10 +112,11 @@ const iconByType = computed(() => {
|
||||
* Call the onConfirm prop (function) and close the Dialog.
|
||||
*/
|
||||
const confirm = () => {
|
||||
console.log("dialog confirmed", input.value.$el);
|
||||
if (input.value !== undefined) {
|
||||
if (!input.value.checkValidity()) {
|
||||
validationMessage.value = input.value.validationMessage;
|
||||
nextTick(() => input.value.select());
|
||||
const inputElement = input.value.$el.querySelector("input");
|
||||
if (!inputElement.checkValidity()) {
|
||||
nextTick(() => inputElement.select());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,9 @@ const props = withDefaults(
|
||||
indefinite?: boolean;
|
||||
}>(),
|
||||
{
|
||||
onAction: () => {},
|
||||
onAction: () => {
|
||||
// do nothing
|
||||
},
|
||||
cancelText: null,
|
||||
variant: "dark",
|
||||
position: "bottom-right",
|
||||
|
@ -13,14 +13,14 @@ import {
|
||||
MAPS_TILES,
|
||||
RESOURCE_PROVIDERS,
|
||||
RESTRICTIONS,
|
||||
ROUTING_TYPE,
|
||||
SEARCH_CONFIG,
|
||||
TIMEZONES,
|
||||
UPLOAD_LIMITS,
|
||||
} from "@/graphql/config";
|
||||
import { IAnonymousParticipationConfig, IConfig } from "@/types/config.model";
|
||||
import { ApolloError } from "@apollo/client/core";
|
||||
import { IConfig } from "@/types/config.model";
|
||||
import { useQuery } from "@vue/apollo-composable";
|
||||
import { computed, ref } from "vue";
|
||||
import { computed } from "vue";
|
||||
|
||||
export function useTimezones() {
|
||||
const {
|
||||
@ -36,26 +36,19 @@ export function useTimezones() {
|
||||
}
|
||||
|
||||
export function useAnonymousParticipationConfig() {
|
||||
const anonymousParticipationConfig = ref<
|
||||
IAnonymousParticipationConfig | undefined
|
||||
>(undefined);
|
||||
const {
|
||||
result: configResult,
|
||||
error,
|
||||
loading,
|
||||
} = useQuery<{
|
||||
config: Pick<IConfig, "anonymous">;
|
||||
}>(ANONYMOUS_PARTICIPATION_CONFIG);
|
||||
|
||||
const error = ref<ApolloError | null>(null);
|
||||
const anonymousParticipationConfig = computed(
|
||||
() => configResult.value?.config?.anonymous?.participation
|
||||
);
|
||||
|
||||
if (!anonymousParticipationConfig.value) {
|
||||
const { onError, onResult } = useQuery<{
|
||||
config: Pick<IConfig, "anonymous">;
|
||||
}>(ANONYMOUS_PARTICIPATION_CONFIG);
|
||||
|
||||
onResult(({ data }) => {
|
||||
anonymousParticipationConfig.value =
|
||||
data.config?.anonymous?.participation;
|
||||
});
|
||||
|
||||
onError((err) => (error.value = err));
|
||||
}
|
||||
|
||||
return { anonymousParticipationConfig, error };
|
||||
return { anonymousParticipationConfig, error, loading };
|
||||
}
|
||||
|
||||
export function useAnonymousReportsConfig() {
|
||||
@ -147,6 +140,15 @@ export function useMapTiles() {
|
||||
return { tiles, error, loading };
|
||||
}
|
||||
|
||||
export function useRoutingType() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "maps">;
|
||||
}>(ROUTING_TYPE);
|
||||
|
||||
const routingType = computed(() => result.value?.config.maps.routing.type);
|
||||
return { routingType, error, loading };
|
||||
}
|
||||
|
||||
export function useFeatures() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "features">;
|
||||
|
@ -55,7 +55,7 @@ export function useGroup(
|
||||
name: unref(name),
|
||||
...options,
|
||||
}),
|
||||
() => ({ enabled: unref(name) !== undefined })
|
||||
() => ({ enabled: unref(name) !== undefined && unref(name) !== "" })
|
||||
);
|
||||
const group = computed(() => result.value?.group);
|
||||
return { group, error, loading, onResult, onError, refetch };
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { computed } from "vue";
|
||||
import { useExportFormats, useUploadLimits } from "./apollo/config";
|
||||
|
||||
export const useHost = (): string => {
|
||||
|
@ -347,6 +347,18 @@ export const MAPS_TILES = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
export const ROUTING_TYPE = gql`
|
||||
query RoutingType {
|
||||
config {
|
||||
maps {
|
||||
routing {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const FEATURES = gql`
|
||||
query Features {
|
||||
config {
|
||||
|
@ -19,6 +19,7 @@ export class Dialog {
|
||||
onConfirm,
|
||||
onCancel,
|
||||
inputAttrs,
|
||||
hasInput,
|
||||
}: {
|
||||
title?: string;
|
||||
message: string;
|
||||
@ -29,7 +30,8 @@ export class Dialog {
|
||||
size?: string;
|
||||
onConfirm?: (prompt: string) => void;
|
||||
onCancel?: (source: string) => void;
|
||||
inputAttrs: Record<string, any>;
|
||||
inputAttrs?: Record<string, any>;
|
||||
hasInput?: boolean;
|
||||
}) {
|
||||
this.app.config.globalProperties.$oruga.modal.open({
|
||||
component: DialogComponent,
|
||||
@ -44,6 +46,7 @@ export class Dialog {
|
||||
onConfirm,
|
||||
onCancel,
|
||||
inputAttrs,
|
||||
hasInput,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ export const routes = [
|
||||
{
|
||||
path: "/about",
|
||||
name: RouteName.ABOUT,
|
||||
component: (): Promise<any> => import("@/views/About.vue"),
|
||||
component: (): Promise<any> => import("@/views/AboutView.vue"),
|
||||
meta: { requiredAuth: false },
|
||||
redirect: { name: RouteName.ABOUT_INSTANCE },
|
||||
children: [
|
||||
|
@ -1,36 +1,53 @@
|
||||
<template>
|
||||
<div class="p-6">
|
||||
<div>
|
||||
<header class="">
|
||||
<h2 class="">{{ $t("Pick an identity") }}</h2>
|
||||
<h2 class="">{{ t("Pick an identity") }}</h2>
|
||||
</header>
|
||||
<section class="">
|
||||
<div class="list is-hoverable list-none">
|
||||
<a
|
||||
class="my-2 block dark:bg-violet-3 rounded-xl p-2"
|
||||
<transition-group
|
||||
tag="ul"
|
||||
class="grid grid-cols-1 gap-y-3 m-5 max-w-md"
|
||||
enter-active-class="duration-300 ease-out"
|
||||
enter-from-class="transform opacity-0"
|
||||
enter-to-class="opacity-100"
|
||||
leave-active-class="duration-200 ease-in"
|
||||
leave-from-class="opacity-100"
|
||||
leave-to-class="transform opacity-0"
|
||||
>
|
||||
<li
|
||||
class="relative focus-within:shadow-lg"
|
||||
v-for="identity in identities"
|
||||
:key="identity.id"
|
||||
:class="{
|
||||
active: currentIdentity && identity.id === currentIdentity.id,
|
||||
}"
|
||||
@click="currentIdentity = identity"
|
||||
:key="identity?.id"
|
||||
>
|
||||
<div class="flex gap-2">
|
||||
<img
|
||||
class="rounded"
|
||||
v-if="identity.avatar"
|
||||
:src="identity.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
height="48"
|
||||
/>
|
||||
<input
|
||||
class="sr-only peer"
|
||||
type="radio"
|
||||
:value="identity"
|
||||
name="availableActors"
|
||||
v-model="currentIdentity"
|
||||
:id="`availableActor-${identity?.id}`"
|
||||
/>
|
||||
<label
|
||||
class="flex flex-wrap p-3 bg-white hover:bg-gray-50 dark:bg-violet-3 dark:hover:bg-violet-3/60 border border-gray-300 rounded-lg cursor-pointer peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent"
|
||||
:for="`availableActor-${identity?.id}`"
|
||||
>
|
||||
<figure class="h-12 w-12" v-if="identity?.avatar">
|
||||
<img
|
||||
class="rounded-full h-full w-full object-cover"
|
||||
:src="identity.avatar.url"
|
||||
alt=""
|
||||
width="48"
|
||||
height="48"
|
||||
/>
|
||||
</figure>
|
||||
<AccountCircle v-else :size="48" />
|
||||
<div class="">
|
||||
<p>@{{ identity.preferredUsername }}</p>
|
||||
<small>{{ identity.name }}</small>
|
||||
<div class="flex-1">
|
||||
<h3>{{ identity?.name }}</h3>
|
||||
<small>{{ `@${identity?.preferredUsername}` }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</transition-group>
|
||||
</section>
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { useI18n } from "vue-i18n";
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
|
@ -321,7 +321,7 @@ import {
|
||||
import { Dialog } from "@/plugins/dialog";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const EVENTS_PER_PAGE = 10;
|
||||
const POSTS_PER_PAGE = 10;
|
||||
|
@ -308,7 +308,7 @@ import {
|
||||
formatDateTimeString,
|
||||
} from "@/filters/datetime";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const EVENTS_PER_PAGE = 10;
|
||||
const PARTICIPATIONS_PER_PAGE = 10;
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="user" class="section">
|
||||
<div v-if="user">
|
||||
<breadcrumbs-nav
|
||||
:links="[
|
||||
{ name: RouteName.ADMIN, text: t('Admin') },
|
||||
@ -18,10 +18,10 @@
|
||||
<section>
|
||||
<h2 class="text-lg font-bold mb-3">{{ t("Details") }}</h2>
|
||||
<div class="flex flex-col">
|
||||
<div class="overflow-x-auto sm:-mx-6">
|
||||
<div class="overflow-x-auto">
|
||||
<div class="inline-block py-2 min-w-full sm:px-2">
|
||||
<div class="overflow-hidden shadow-md sm:rounded-lg">
|
||||
<table v-if="metadata.length > 0" class="min-w-full">
|
||||
<table v-if="metadata.length > 0" class="table w-full">
|
||||
<tbody>
|
||||
<tr
|
||||
class="border-b"
|
||||
@ -229,48 +229,46 @@
|
||||
aria-modal
|
||||
>
|
||||
<form @submit.prevent="updateUserRole">
|
||||
<div>
|
||||
<header>
|
||||
<h2 class="modal-card-title">{{ t("Change user role") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.ADMINISTRATOR"
|
||||
>
|
||||
{{ t("Administrator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.MODERATOR"
|
||||
>
|
||||
{{ t("Moderator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.USER"
|
||||
>
|
||||
{{ t("User") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer class="mt-2 flex gap-2">
|
||||
<o-button @click="isRoleChangeModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Change role")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</div>
|
||||
<header>
|
||||
<h2>{{ t("Change user role") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.ADMINISTRATOR"
|
||||
>
|
||||
{{ t("Administrator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.MODERATOR"
|
||||
>
|
||||
{{ t("Moderator") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-field>
|
||||
<o-radio
|
||||
v-model="newUser.role"
|
||||
:native-value="ICurrentUserRole.USER"
|
||||
>
|
||||
{{ t("User") }}
|
||||
</o-radio>
|
||||
</o-field>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer class="mt-2 flex gap-2">
|
||||
<o-button @click="isRoleChangeModalActive = false" outlined>{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Change role")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</form>
|
||||
</o-modal>
|
||||
<o-modal
|
||||
@ -284,24 +282,22 @@
|
||||
aria-modal
|
||||
>
|
||||
<form @submit.prevent="confirmUser">
|
||||
<div>
|
||||
<header>
|
||||
<h2>{{ t("Confirm user") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer>
|
||||
<o-button @click="isConfirmationModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Confirm user")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</div>
|
||||
<header>
|
||||
<h2>{{ t("Confirm user") }}</h2>
|
||||
</header>
|
||||
<section>
|
||||
<o-checkbox v-model="newUser.notify">{{
|
||||
t("Notify the user of the change")
|
||||
}}</o-checkbox>
|
||||
</section>
|
||||
<footer>
|
||||
<o-button @click="isConfirmationModalActive = false">{{
|
||||
t("Close")
|
||||
}}</o-button>
|
||||
<o-button native-type="submit" variant="primary">{{
|
||||
t("Confirm user")
|
||||
}}</o-button>
|
||||
</footer>
|
||||
</form>
|
||||
</o-modal>
|
||||
</div>
|
||||
@ -424,7 +420,7 @@ const metadata = computed(
|
||||
},
|
||||
{
|
||||
key: t("Uploaded media total size"),
|
||||
value: formatBytes(user.value.mediaSize, 2, t("0 Bytes")),
|
||||
value: formatBytes(user.value.mediaSize),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
@ -443,10 +443,10 @@ const instanceLanguages = computed({
|
||||
return codeForLanguage(language);
|
||||
})
|
||||
.filter((code) => code !== undefined) as string[];
|
||||
// adminSettings = {
|
||||
// ...adminSettings,
|
||||
// instanceLanguages: newInstanceLanguages,
|
||||
// };
|
||||
settingsToWrite.value = {
|
||||
...settingsToWrite.value,
|
||||
instanceLanguages: newFilteredInstanceLanguages,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -218,10 +218,7 @@
|
||||
</p>
|
||||
<o-dropdown>
|
||||
<template #trigger>
|
||||
<o-button
|
||||
icon-right="dots-horizontal"
|
||||
#default="{ active }"
|
||||
>
|
||||
<o-button icon-right="dots-horizontal">
|
||||
{{ t("Actions") }}
|
||||
</o-button>
|
||||
</template>
|
||||
@ -260,8 +257,8 @@
|
||||
<o-dropdown-item
|
||||
aria-role="listitem"
|
||||
v-if="canManageEvent || event?.draft"
|
||||
@click="openDeleteEventModalWrapper"
|
||||
@keyup.enter="openDeleteEventModalWrapper"
|
||||
@click="openDeleteEventModal"
|
||||
@keyup.enter="openDeleteEventModal"
|
||||
><span class="flex gap-1">
|
||||
<Delete />
|
||||
{{ t("Delete") }}
|
||||
@ -386,7 +383,11 @@
|
||||
has-modal-card
|
||||
ref="shareModal"
|
||||
>
|
||||
<share-event-modal :event="event" :eventCapacityOK="eventCapacityOK" />
|
||||
<share-event-modal
|
||||
v-if="event"
|
||||
:event="event"
|
||||
:eventCapacityOK="eventCapacityOK"
|
||||
/>
|
||||
</o-modal>
|
||||
<o-modal
|
||||
v-model:active="isJoinModalActive"
|
||||
@ -394,34 +395,34 @@
|
||||
ref="participationModal"
|
||||
:close-button-aria-label="t('Close')"
|
||||
>
|
||||
<identity-picker v-model="identity">
|
||||
<identity-picker v-if="identity" v-model="identity">
|
||||
<template #footer>
|
||||
<footer class="modal-card-foot">
|
||||
<button
|
||||
class="button"
|
||||
<footer class="flex gap-2">
|
||||
<o-button
|
||||
outlined
|
||||
ref="cancelButton"
|
||||
@click="isJoinModalActive = false"
|
||||
@keyup.enter="isJoinModalActive = false"
|
||||
>
|
||||
{{ t("Cancel") }}
|
||||
</button>
|
||||
<button
|
||||
</o-button>
|
||||
<o-button
|
||||
v-if="identity"
|
||||
class="button is-primary"
|
||||
variant="primary"
|
||||
ref="confirmButton"
|
||||
@click="
|
||||
event?.joinOptions === EventJoinOptions.RESTRICTED
|
||||
? joinEventWithConfirmation(identity)
|
||||
: joinEvent(identity)
|
||||
? joinEventWithConfirmation(identity as IPerson)
|
||||
: joinEvent(identity as IPerson)
|
||||
"
|
||||
@keyup.enter="
|
||||
event?.joinOptions === EventJoinOptions.RESTRICTED
|
||||
? joinEventWithConfirmation(identity)
|
||||
: joinEvent(identity)
|
||||
? joinEventWithConfirmation(identity as IPerson)
|
||||
: joinEvent(identity as IPerson)
|
||||
"
|
||||
>
|
||||
{{ t("Confirm my particpation") }}
|
||||
</button>
|
||||
</o-button>
|
||||
</footer>
|
||||
</template>
|
||||
</identity-picker>
|
||||
@ -449,7 +450,10 @@
|
||||
</p>
|
||||
<form
|
||||
@submit.prevent="
|
||||
joinEvent(actorForConfirmation, messageForConfirmation)
|
||||
joinEvent(
|
||||
actorForConfirmation as IPerson,
|
||||
messageForConfirmation
|
||||
)
|
||||
"
|
||||
>
|
||||
<o-field :label="t('Message')">
|
||||
@ -487,22 +491,13 @@
|
||||
:can-cancel="['escape', 'outside']"
|
||||
>
|
||||
<template #default="props">
|
||||
<!-- <event-map
|
||||
:routingType="routingType"
|
||||
<event-map
|
||||
:routingType="routingType ?? RoutingType.OPENSTREETMAP"
|
||||
:address="event.physicalAddress"
|
||||
@close="props.close"
|
||||
/> -->
|
||||
/>
|
||||
</template>
|
||||
</o-modal>
|
||||
<dialog
|
||||
variant="danger"
|
||||
:title="t('Delete event')"
|
||||
:message="deleteEventMessage"
|
||||
:confirmText="t('Delete {eventTitle}', { eventTitle: event?.title })"
|
||||
:onConfirm="
|
||||
() => (event?.id ? deleteEvent({ eventId: event?.id }) : null)
|
||||
"
|
||||
></dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -514,12 +509,14 @@ import {
|
||||
EventVisibility,
|
||||
MemberRole,
|
||||
ParticipantRole,
|
||||
RoutingType,
|
||||
} from "@/types/enums";
|
||||
import {
|
||||
EVENT_PERSON_PARTICIPATION,
|
||||
EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
||||
// EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED,
|
||||
FETCH_EVENT,
|
||||
JOIN_EVENT,
|
||||
LEAVE_EVENT,
|
||||
} from "@/graphql/event";
|
||||
import { IEvent } from "@/types/event.model";
|
||||
import {
|
||||
@ -543,7 +540,7 @@ import {
|
||||
isParticipatingInThisEvent,
|
||||
removeAnonymousParticipation,
|
||||
} from "@/services/AnonymousParticipationStorage";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import EventMetadataSidebar from "@/components/Event/EventMetadataSidebar.vue";
|
||||
import EventBanner from "@/components/Event/EventBanner.vue";
|
||||
import EventMap from "@/components/Event/EventMap.vue";
|
||||
@ -583,19 +580,21 @@ import {
|
||||
useAnonymousParticipationConfig,
|
||||
useAnonymousReportsConfig,
|
||||
useEventCategories,
|
||||
useRoutingType,
|
||||
} from "@/composition/apollo/config";
|
||||
import { useCreateReport } from "@/composition/apollo/report";
|
||||
import Share from "vue-material-design-icons/Share.vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useProgrammatic } from "@oruga-ui/oruga-next";
|
||||
import { Dialog } from "@/plugins/dialog";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import { AbsintheGraphQLErrors } from "@/types/errors.model";
|
||||
import { useHead } from "@vueuse/head";
|
||||
import { Snackbar } from "@/plugins/snackbar";
|
||||
|
||||
const ShareEventModal = defineAsyncComponent(
|
||||
() => import("@/components/Event/ShareEventModal.vue")
|
||||
);
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
const IntegrationTwitch = defineAsyncComponent(
|
||||
() => import("@/components/Event/Integrations/TwitchIntegration.vue")
|
||||
);
|
||||
@ -611,6 +610,7 @@ const IntegrationJitsiMeet = defineAsyncComponent(
|
||||
const IntegrationEtherpad = defineAsyncComponent(
|
||||
() => import("@/components/Event/Integrations/EtherpadIntegration.vue")
|
||||
);
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
||||
const props = defineProps<{
|
||||
uuid: string;
|
||||
@ -629,7 +629,7 @@ const currentActorId = computed(() => currentActor.value?.id);
|
||||
const { loggedUser } = useLoggedUser();
|
||||
const {
|
||||
result: participationsResult,
|
||||
subscribeToMore: subscribeToMoreParticipation,
|
||||
// subscribeToMore: subscribeToMoreParticipation,
|
||||
} = useQuery<{ person: IPerson }>(
|
||||
EVENT_PERSON_PARTICIPATION,
|
||||
() => ({
|
||||
@ -653,7 +653,7 @@ const {
|
||||
// }));
|
||||
|
||||
const participations = computed(
|
||||
() => participationsResult.value?.person.participations.elements ?? []
|
||||
() => participationsResult.value?.person.participations?.elements ?? []
|
||||
);
|
||||
|
||||
const { person } = usePersonStatusGroup(
|
||||
@ -680,7 +680,7 @@ const { identities } = useCurrentUserIdentities();
|
||||
// };
|
||||
// },
|
||||
|
||||
const identity = ref<IPerson | null>(null);
|
||||
const identity = ref<IPerson | undefined | null>(null);
|
||||
|
||||
const reportModal = ref();
|
||||
const oldParticipationRole = ref<string | undefined>(undefined);
|
||||
@ -786,12 +786,6 @@ onMounted(async () => {
|
||||
// return router.push({ name: RouteName.HOME });
|
||||
// });
|
||||
});
|
||||
/**
|
||||
* Delete the event, then redirect to home.
|
||||
*/
|
||||
const openDeleteEventModalWrapper = async (): Promise<void> => {
|
||||
await openDeleteEventModal(event.value);
|
||||
};
|
||||
|
||||
const deleteEventMessage = computed(() => {
|
||||
const participantsLength = event.value?.participantStats.participant;
|
||||
@ -814,17 +808,62 @@ const deleteEventMessage = computed(() => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
const { mutate: deleteEvent } = useDeleteEvent();
|
||||
const notifier = inject<Notifier>("notifier");
|
||||
const dialog = inject<Dialog>("dialog");
|
||||
|
||||
const openDeleteEventModal = async (
|
||||
event: IEvent | undefined
|
||||
): Promise<void> => {
|
||||
function escapeRegExp(string: string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
}
|
||||
const {
|
||||
mutate: deleteEvent,
|
||||
onDone: onDeleteEventDone,
|
||||
onError: onDeleteEventError,
|
||||
} = useDeleteEvent();
|
||||
|
||||
const escapeRegExp = (string: string) => {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
};
|
||||
|
||||
const notifier = inject<Notifier>("notifier");
|
||||
const openDeleteEventModal = () => {
|
||||
dialog?.prompt({
|
||||
title: t("Delete event"),
|
||||
message: deleteEventMessage.value,
|
||||
confirmText: t("Delete event"),
|
||||
cancelText: t("Cancel"),
|
||||
variant: "danger",
|
||||
hasIcon: true,
|
||||
hasInput: true,
|
||||
inputAttrs: {
|
||||
placeholder: event.value?.title,
|
||||
pattern: escapeRegExp(event.value?.title ?? ""),
|
||||
},
|
||||
onConfirm: (result: string) => {
|
||||
console.log("calling delete event", result);
|
||||
if (result.trim() === event.value?.title) {
|
||||
event.value?.id ? deleteEvent({ eventId: event.value?.id }) : null;
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
onDeleteEventDone(() => {
|
||||
router.push({ name: RouteName.MY_EVENTS });
|
||||
});
|
||||
|
||||
onDeleteEventError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const {
|
||||
mutate: createReportMutation,
|
||||
onDone: onCreateReportDone,
|
||||
onError: onCreateReportError,
|
||||
} = useCreateReport();
|
||||
|
||||
onCreateReportDone(() => {
|
||||
notifier?.success(t("Event {eventTitle} reported", { eventTitle }));
|
||||
});
|
||||
|
||||
onCreateReportError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const reportEvent = async (
|
||||
content: string,
|
||||
@ -836,22 +875,12 @@ const reportEvent = async (
|
||||
reportModal.value.close();
|
||||
if (!organizer.value) return;
|
||||
|
||||
const { mutate, onDone, onError } = useCreateReport();
|
||||
|
||||
mutate({
|
||||
createReportMutation({
|
||||
eventId: event.value?.id ?? "",
|
||||
reportedId: organizer.value?.id ?? "",
|
||||
content,
|
||||
forward,
|
||||
});
|
||||
|
||||
onDone(() => {
|
||||
notifier?.success(t("Event {eventTitle} reported", { eventTitle }));
|
||||
});
|
||||
|
||||
onError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
};
|
||||
|
||||
const joinEventWithConfirmation = (actor: IPerson): void => {
|
||||
@ -876,7 +905,7 @@ const {
|
||||
|
||||
const participationCachedData = store.readQuery<{ person: IPerson }>({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: event.value?.id, actorId: identity.value.id },
|
||||
variables: { eventId: event.value?.id, actorId: identity.value?.id },
|
||||
});
|
||||
|
||||
if (participationCachedData?.person == undefined) {
|
||||
@ -887,7 +916,7 @@ const {
|
||||
}
|
||||
store.writeQuery({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: event.value?.id, actorId: identity.value.id },
|
||||
variables: { eventId: event.value?.id, actorId: identity.value?.id },
|
||||
data: {
|
||||
person: {
|
||||
...participationCachedData?.person,
|
||||
@ -934,14 +963,14 @@ const {
|
||||
}));
|
||||
|
||||
const joinEvent = async (
|
||||
identity: IPerson,
|
||||
identityForJoin: IPerson,
|
||||
message: string | null = null
|
||||
): Promise<void> => {
|
||||
isJoinConfirmationModalActive.value = false;
|
||||
isJoinModalActive.value = false;
|
||||
joinEventMutation({
|
||||
eventId: event.value?.id,
|
||||
actorId: identity?.id,
|
||||
actorId: identityForJoin?.id,
|
||||
message,
|
||||
});
|
||||
};
|
||||
@ -960,8 +989,6 @@ onJoinEventMutationError((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
const dialog = inject<Dialog>("dialog");
|
||||
|
||||
const confirmLeave = (): void => {
|
||||
dialog?.confirm({
|
||||
title: t('Leaving event "{title}"', {
|
||||
@ -975,10 +1002,11 @@ const confirmLeave = (): void => {
|
||||
),
|
||||
confirmText: t("Leave event"),
|
||||
cancelText: t("Cancel"),
|
||||
type: "danger",
|
||||
variant: "danger",
|
||||
hasIcon: true,
|
||||
onConfirm: () => {
|
||||
if (currentActor.value?.id) {
|
||||
if (event.value && currentActor.value?.id) {
|
||||
console.log("calling leave event");
|
||||
leaveEvent(event.value, currentActor.value.id);
|
||||
}
|
||||
},
|
||||
@ -1071,14 +1099,14 @@ onFetchEventError(({ graphQLErrors }) =>
|
||||
handleErrors(graphQLErrors as AbsintheGraphQLErrors)
|
||||
);
|
||||
|
||||
const actorIsParticipant = computed((): boolean => {
|
||||
if (actorIsOrganizer.value) return true;
|
||||
// const actorIsParticipant = computed((): boolean => {
|
||||
// if (actorIsOrganizer.value) return true;
|
||||
|
||||
return (
|
||||
participations.value.length > 0 &&
|
||||
participations.value[0].role === ParticipantRole.PARTICIPANT
|
||||
);
|
||||
});
|
||||
// return (
|
||||
// participations.value.length > 0 &&
|
||||
// participations.value[0].role === ParticipantRole.PARTICIPANT
|
||||
// );
|
||||
// });
|
||||
|
||||
const actorIsOrganizer = computed((): boolean => {
|
||||
return (
|
||||
@ -1101,11 +1129,11 @@ const canManageEvent = computed((): boolean => {
|
||||
return actorIsOrganizer.value || hasGroupPrivileges.value;
|
||||
});
|
||||
|
||||
const endDate = computed((): string | undefined => {
|
||||
return event.value?.endsOn && event.value.endsOn > event.value.beginsOn
|
||||
? event.value.endsOn
|
||||
: event.value?.beginsOn;
|
||||
});
|
||||
// const endDate = computed((): string | undefined => {
|
||||
// return event.value?.endsOn && event.value.endsOn > event.value.beginsOn
|
||||
// ? event.value.endsOn
|
||||
// : event.value?.beginsOn;
|
||||
// });
|
||||
|
||||
const maximumAttendeeCapacity = computed((): number | undefined => {
|
||||
return event.value?.options?.maximumAttendeeCapacity;
|
||||
@ -1122,21 +1150,22 @@ const eventCapacityOK = computed((): boolean => {
|
||||
);
|
||||
});
|
||||
|
||||
const numberOfPlacesStillAvailable = computed((): number | undefined => {
|
||||
if (event.value?.draft) return maximumAttendeeCapacity.value;
|
||||
return (
|
||||
(maximumAttendeeCapacity.value ?? 0) -
|
||||
(event.value?.participantStats.participant ?? 0)
|
||||
);
|
||||
});
|
||||
// const numberOfPlacesStillAvailable = computed((): number | undefined => {
|
||||
// if (event.value?.draft) return maximumAttendeeCapacity.value;
|
||||
// return (
|
||||
// (maximumAttendeeCapacity.value ?? 0) -
|
||||
// (event.value?.participantStats.participant ?? 0)
|
||||
// );
|
||||
// });
|
||||
|
||||
const anonymousParticipationConfirmed = async (): Promise<boolean> => {
|
||||
return isParticipatingInThisEvent(props.uuid);
|
||||
};
|
||||
|
||||
const cancelAnonymousParticipation = async (): Promise<void> => {
|
||||
if (!event.value || !anonymousActorId.value) return;
|
||||
const token = (await getLeaveTokenForParticipation(props.uuid)) as string;
|
||||
await leaveEvent(event.value, anonymousActorId.value, token);
|
||||
leaveEvent(event.value, anonymousActorId.value, token);
|
||||
await removeAnonymousParticipation(props.uuid);
|
||||
anonymousParticipation.value = null;
|
||||
};
|
||||
@ -1192,19 +1221,134 @@ const integrations = computed((): Record<string, IEventMetadataDescription> => {
|
||||
|
||||
const showMap = ref(false);
|
||||
|
||||
const routingType = computed((): string | undefined => {
|
||||
return config.value?.maps?.routing?.type;
|
||||
});
|
||||
const { routingType } = useRoutingType();
|
||||
|
||||
const eventCategory = computed((): string | undefined => {
|
||||
if (event.value?.category === "MEETING") {
|
||||
return undefined;
|
||||
}
|
||||
return (eventCategories.value ?? []).find((eventCategory) => {
|
||||
return eventCategory.id === event.value?.category;
|
||||
return (eventCategories.value ?? []).find((eventCategoryToFind) => {
|
||||
return eventCategoryToFind.id === event.value?.category;
|
||||
})?.label as string;
|
||||
});
|
||||
|
||||
const {
|
||||
mutate: leaveEventMutation,
|
||||
onDone: onLeaveEventMutationDone,
|
||||
onError: onLeaveEventMutationError,
|
||||
} = useMutation<{ leaveEvent: { actor: { id: string } } }>(LEAVE_EVENT, () => ({
|
||||
update: (
|
||||
store: ApolloCache<{
|
||||
leaveEvent: IParticipant;
|
||||
}>,
|
||||
{ data }: FetchResult,
|
||||
{ context, variables }
|
||||
) => {
|
||||
if (data == null) return;
|
||||
let participation;
|
||||
|
||||
const token = context?.token;
|
||||
const actorId = variables?.actorId;
|
||||
const localEventId = variables?.eventId;
|
||||
const eventUUID = context?.eventUUID;
|
||||
const isAnonymousParticipationConfirmed =
|
||||
context?.isAnonymousParticipationConfirmed;
|
||||
|
||||
if (!token) {
|
||||
const participationCachedData = store.readQuery<{
|
||||
person: IPerson;
|
||||
}>({
|
||||
query: EVENT_PERSON_PARTICIPATION,
|
||||
variables: { eventId: localEventId, actorId },
|
||||
});
|
||||
if (participationCachedData == null) return;
|
||||
const { person: cachedPerson } = participationCachedData;
|
||||
[participation] = cachedPerson?.participations?.elements ?? [undefined];
|
||||
|
||||
store.modify({
|
||||
id: `Person:${actorId}`,
|
||||
fields: {
|
||||
participations() {
|
||||
return {
|
||||
elements: [],
|
||||
total: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const eventCachedData = store.readQuery<{ event: IEvent }>({
|
||||
query: FETCH_EVENT,
|
||||
variables: { uuid: eventUUID },
|
||||
});
|
||||
if (eventCachedData == null) return;
|
||||
const { event: eventCached } = eventCachedData;
|
||||
if (eventCached === null) {
|
||||
console.error("Cannot update event cache, because of null value.");
|
||||
return;
|
||||
}
|
||||
const participantStats = { ...eventCached.participantStats };
|
||||
if (participation && participation?.role === ParticipantRole.NOT_APPROVED) {
|
||||
participantStats.notApproved -= 1;
|
||||
} else if (isAnonymousParticipationConfirmed === false) {
|
||||
participantStats.notConfirmed -= 1;
|
||||
} else {
|
||||
participantStats.going -= 1;
|
||||
participantStats.participant -= 1;
|
||||
}
|
||||
store.writeQuery({
|
||||
query: FETCH_EVENT,
|
||||
variables: { uuid: eventUUID },
|
||||
data: {
|
||||
event: {
|
||||
...eventCached,
|
||||
participantStats,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
const leaveEvent = (
|
||||
eventToLeave: IEvent,
|
||||
actorId: string,
|
||||
token: string | null = null,
|
||||
isAnonymousParticipationConfirmed: boolean | null = null
|
||||
): void => {
|
||||
leaveEventMutation(
|
||||
{
|
||||
eventId: eventToLeave.id,
|
||||
actorId,
|
||||
token,
|
||||
},
|
||||
{
|
||||
context: {
|
||||
token,
|
||||
isAnonymousParticipationConfirmed,
|
||||
eventUUID: eventToLeave.uuid,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
onLeaveEventMutationDone(({ data }) => {
|
||||
if (data) {
|
||||
notifier?.success(t("You have cancelled your participation"));
|
||||
}
|
||||
});
|
||||
|
||||
const snackbar = inject<Snackbar>("snackbar");
|
||||
|
||||
onLeaveEventMutationError((error) => {
|
||||
snackbar?.open({
|
||||
message: error.message,
|
||||
variant: "danger",
|
||||
position: "bottom",
|
||||
});
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
useHead({
|
||||
title: computed(() => eventTitle.value ?? ""),
|
||||
meta: [{ name: "description", content: eventDescription.value }],
|
||||
|
@ -97,7 +97,6 @@
|
||||
<event-participation-card
|
||||
v-if="'role' in element"
|
||||
:participation="element"
|
||||
:options="{ hideDate: false }"
|
||||
@event-deleted="eventDeleted"
|
||||
class="participation"
|
||||
/>
|
||||
|
@ -283,7 +283,7 @@ import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import Incognito from "vue-material-design-icons/Incognito.vue";
|
||||
import EmptyContent from "@/components/Utils/EmptyContent.vue";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const PARTICIPANTS_PER_PAGE = 10;
|
||||
const MESSAGE_ELLIPSIS_LENGTH = 130;
|
||||
|
@ -267,7 +267,7 @@ import {
|
||||
import { formatTimeString, formatDateString } from "@/filters/datetime";
|
||||
import AccountCircle from "vue-material-design-icons/AccountCircle.vue";
|
||||
import { Notifier } from "@/plugins/notifier";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
|
||||
const { t } = useI18n({ useScope: "global" });
|
||||
|
||||
|
@ -135,7 +135,7 @@ import { IGroup, usernameWithDomain, displayName } from "@/types/actor";
|
||||
import { ActivityType } from "@/types/enums";
|
||||
import { Paginate } from "@/types/paginate";
|
||||
import { IActivity } from "../../types/activity.model";
|
||||
import Observer from "../../components/Utils/Observer.vue";
|
||||
import Observer from "../../components/Utils/ObserverElement.vue";
|
||||
import SkeletonActivityItem from "../../components/Activity/SkeletonActivityItem.vue";
|
||||
import RouteName from "../../router/name";
|
||||
import TimelineText from "vue-material-design-icons/TimelineText.vue";
|
||||
|
@ -219,7 +219,7 @@ import {
|
||||
displayName,
|
||||
} from "@/types/actor";
|
||||
import RouteName from "@/router/name";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import LazyImageWrapper from "@/components/Image/LazyImageWrapper.vue";
|
||||
import ActorInline from "@/components/Account/ActorInline.vue";
|
||||
import { formatDistanceToNowStrict, Locale } from "date-fns";
|
||||
|
@ -202,7 +202,6 @@ import {
|
||||
InternalRefetchQueriesInclude,
|
||||
} from "@apollo/client/core";
|
||||
import { useMutation, useQuery } from "@vue/apollo-composable";
|
||||
import { useCurrentActorClient } from "@/composition/apollo/actor";
|
||||
import { computed, nextTick, reactive, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { integerTransformer, useRouteQuery } from "vue-use-route-query";
|
||||
@ -275,7 +274,7 @@ const moveModal = ref(false);
|
||||
const renameModal = ref(false);
|
||||
const modalError = ref("");
|
||||
|
||||
const resourceRenameInput = ref<HTMLElement>();
|
||||
const resourceRenameInput = ref<any>();
|
||||
const modalNewResourceInput = ref<HTMLElement>();
|
||||
const modalNewResourceLinkInput = ref<HTMLElement>();
|
||||
|
||||
@ -307,7 +306,7 @@ const {
|
||||
refetchQueries: () => postRefreshQueries(),
|
||||
}));
|
||||
|
||||
createResourceDone(({ data }) => {
|
||||
createResourceDone(() => {
|
||||
createLinkResourceModal.value = false;
|
||||
createResourceModal.value = false;
|
||||
newResource.title = "";
|
||||
@ -447,25 +446,25 @@ const { mutate: deleteResource, onError: onDeleteResourceError } = useMutation(
|
||||
|
||||
onDeleteResourceError((e) => console.error(e));
|
||||
|
||||
const handleRename = async (resource: IResource): Promise<void> => {
|
||||
const handleRename = async (resourceToRename: IResource): Promise<void> => {
|
||||
renameModal.value = true;
|
||||
updatedResource.value = { ...resource };
|
||||
updatedResource.value = { ...resourceToRename };
|
||||
await nextTick();
|
||||
resourceRenameInput.value?.$el.focus();
|
||||
resourceRenameInput.value?.$el.querySelector("input")?.select();
|
||||
};
|
||||
|
||||
const handleMove = (resource: IResource): void => {
|
||||
const handleMove = (resourceToMove: IResource): void => {
|
||||
moveModal.value = true;
|
||||
updatedResource.value = { ...resource };
|
||||
updatedResource.value = { ...resourceToMove };
|
||||
};
|
||||
|
||||
const moveResource = async (
|
||||
resource: IResource,
|
||||
resourceToMove: IResource,
|
||||
oldParent: IResource | undefined
|
||||
): Promise<void> => {
|
||||
const parentPath = oldParent && oldParent.path ? oldParent.path || "/" : "/";
|
||||
await updateResource(resource, parentPath);
|
||||
await updateResource(resourceToMove, parentPath);
|
||||
moveModal.value = false;
|
||||
};
|
||||
|
||||
@ -501,10 +500,10 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
console.error("Cannot update resource cache, because of null value.");
|
||||
return;
|
||||
}
|
||||
const updatedResource: IResource = data.updateResource;
|
||||
const postUpdatedResource: IResource = data.updateResource;
|
||||
|
||||
const updatedElementList = oldParentCachedResource.children.elements.filter(
|
||||
(cachedResource) => cachedResource.id !== updatedResource.id
|
||||
(cachedResource) => cachedResource.id !== postUpdatedResource.id
|
||||
);
|
||||
|
||||
store.writeQuery({
|
||||
@ -526,14 +525,14 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
console.debug("Finished removing ressource from old parent");
|
||||
|
||||
console.debug("Adding resource to new parent");
|
||||
if (!updatedResource.parent || !updatedResource.parent.path) {
|
||||
if (!postUpdatedResource.parent || !postUpdatedResource.parent.path) {
|
||||
console.debug("No cache found for new parent");
|
||||
return;
|
||||
}
|
||||
const newParentCachedData = store.readQuery<{ resource: IResource }>({
|
||||
query: GET_RESOURCE,
|
||||
variables: {
|
||||
path: updatedResource.parent.path,
|
||||
path: postUpdatedResource.parent.path,
|
||||
username: resource.value.actor.preferredUsername,
|
||||
},
|
||||
});
|
||||
@ -547,7 +546,7 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
store.writeQuery({
|
||||
query: GET_RESOURCE,
|
||||
variables: {
|
||||
path: updatedResource.parent.path,
|
||||
path: postUpdatedResource.parent.path,
|
||||
username: resource.value.actor.preferredUsername,
|
||||
},
|
||||
data: {
|
||||
@ -565,15 +564,15 @@ const { mutate: updateResourceMutation } = useMutation<{
|
||||
}));
|
||||
|
||||
const updateResource = async (
|
||||
resource: IResource,
|
||||
resourceToUpdate: IResource,
|
||||
parentPath: string | null = null
|
||||
): Promise<void> => {
|
||||
updateResourceMutation(
|
||||
{
|
||||
id: resource.id,
|
||||
title: resource.title,
|
||||
parentId: resource.parent ? resource.parent.id : null,
|
||||
path: resource.path,
|
||||
id: resourceToUpdate.id,
|
||||
title: resourceToUpdate.title,
|
||||
parentId: resourceToUpdate.parent ? resourceToUpdate.parent.id : null,
|
||||
path: resourceToUpdate.path,
|
||||
},
|
||||
{ context: { parentPath } }
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { mount } from "@vue/test-utils";
|
||||
import Tag from "@/components/Tag.vue";
|
||||
import Tag from "@/components/TagElement.vue";
|
||||
import { it, expect } from "vitest";
|
||||
|
||||
const tagContent = "My tag";
|
||||
|
1585
js/yarn.lock
1585
js/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -23,11 +23,19 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
@spec find_user(any(), map(), Absinthe.Resolution.t()) :: {:ok, User.t()} | {:error, String.t()}
|
||||
def find_user(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_moderator(role) do
|
||||
with {:ok, %User{} = user} <- Users.get_user_with_actors(id) do
|
||||
{:ok, user}
|
||||
case Users.get_user_with_actors(id) do
|
||||
{:ok, %User{} = user} ->
|
||||
{:ok, user}
|
||||
|
||||
_ ->
|
||||
{:error, :user_not_found}
|
||||
end
|
||||
end
|
||||
|
||||
def find_user(_parent, _args, _resolution) do
|
||||
{:error, :unauthorized}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Return current logged-in user
|
||||
"""
|
||||
|
@ -2,9 +2,10 @@
|
||||
<% :event_comment_mention -> %>
|
||||
<%= dgettext("activity", "%{profile} mentionned you in a comment under event %{event}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -12,9 +13,10 @@
|
||||
<% :participation_event_comment -> %>
|
||||
<%= dgettext("activity", "%{profile} has posted an announcement under event %{event}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -23,9 +25,10 @@
|
||||
<%= if @activity.subject_params["comment_reply_to"] do %>
|
||||
<%= dgettext("activity", "%{profile} has posted a new reply under your event %{event}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}#comment-#{@activity.subject_params["comment_reply_to_uuid"]}-#{@activity.subject_params["comment_uuid"]}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}#comment-#{@activity.subject_params["comment_reply_to_uuid"]}-#{@activity.subject_params["comment_uuid"]}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -36,9 +39,10 @@
|
||||
"%{profile} has posted a new comment under your event %{event}.",
|
||||
%{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}#comment-#{@activity.subject_params["comment_uuid"]}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}#comment-#{@activity.subject_params["comment_uuid"]}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
}
|
||||
|
@ -2,9 +2,10 @@
|
||||
<% :event_created -> %>
|
||||
<%= dgettext("activity", "The event %{event} was created by %{profile}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -12,9 +13,10 @@
|
||||
<% :event_updated -> %>
|
||||
<%= dgettext("activity", "The event %{event} was updated by %{profile}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -29,9 +31,10 @@
|
||||
<%= if @activity.subject_params["comment_reply_to"] do %>
|
||||
<%= dgettext("activity", "%{profile} replied to a comment on the event %{event}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -39,9 +42,10 @@
|
||||
<% else %>
|
||||
<%= dgettext("activity", "%{profile} posted a comment on the event %{event}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
})
|
||||
|
@ -2,9 +2,10 @@
|
||||
<% :group_created -> %>
|
||||
<%= dgettext("activity", "%{profile} created the group %{group}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
group: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:actor,
|
||||
@activity.subject_params["group_federated_username"]) |> URI.decode()}\">
|
||||
group:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:actor,
|
||||
@activity.subject_params["group_federated_username"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["group_name"]}
|
||||
</a>"
|
||||
})
|
||||
@ -12,9 +13,10 @@
|
||||
<% :group_updated -> %>
|
||||
<%= dgettext("activity", "%{profile} updated the group %{group}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
group: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:actor,
|
||||
@activity.subject_params["group_federated_username"]) |> URI.decode()}\">
|
||||
group:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:actor,
|
||||
@activity.subject_params["group_federated_username"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["group_name"]}
|
||||
</a>"
|
||||
})
|
||||
|
@ -2,9 +2,10 @@
|
||||
<% :post_created -> %>
|
||||
<%= dgettext("activity", "The post %{post} was created by %{profile}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
post: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:post,
|
||||
@activity.subject_params["post_slug"]) |> URI.decode()}\">
|
||||
post:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:post,
|
||||
@activity.subject_params["post_slug"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["post_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -12,9 +13,10 @@
|
||||
<% :post_updated -> %>
|
||||
<%= dgettext("activity", "The post %{post} was updated by %{profile}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
post: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:post,
|
||||
@activity.subject_params["post_slug"]) |> URI.decode()}\">
|
||||
post:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:post,
|
||||
@activity.subject_params["post_slug"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["post_title"]}
|
||||
</a>"
|
||||
})
|
||||
|
@ -3,9 +3,10 @@
|
||||
<%= if @activity.subject_params["is_folder"] do %>
|
||||
<%= dgettext("activity", "%{profile} created the folder %{resource}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -13,9 +14,10 @@
|
||||
<% else %>
|
||||
<%= dgettext("activity", "%{profile} created the resource %{resource}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -28,9 +30,10 @@
|
||||
"%{profile} renamed the folder from %{old_resource_title} to %{resource}.",
|
||||
%{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>",
|
||||
old_resource_title: "<b>#{@activity.subject_params["old_resource_title"]}</b>"
|
||||
@ -43,9 +46,10 @@
|
||||
"%{profile} renamed the resource from %{old_resource_title} to %{resource}.",
|
||||
%{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>",
|
||||
old_resource_title: "<b>#{@activity.subject_params["old_resource_title"]}</b>"
|
||||
@ -57,9 +61,10 @@
|
||||
<%= if @activity.subject_params["is_folder"] do %>
|
||||
<%= dgettext("activity", "%{profile} moved the folder %{resource}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>"
|
||||
})
|
||||
@ -67,9 +72,10 @@
|
||||
<% else %>
|
||||
<%= dgettext("activity", "%{profile} moved the resource %{resource}.", %{
|
||||
profile: "<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
resource: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
resource:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:resource,
|
||||
@activity.subject_params["resource_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["resource_title"]}
|
||||
</a>"
|
||||
})
|
||||
|
@ -51,9 +51,10 @@
|
||||
%{
|
||||
profile:
|
||||
"<b>#{Mobilizon.Actors.Actor.display_name_and_username(@activity.author)}</b>",
|
||||
event: "<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
event:
|
||||
"<a href=\"#{Routes.page_url(Mobilizon.Web.Endpoint,
|
||||
:event,
|
||||
@activity.subject_params["event_uuid"]) |> URI.decode()}\">
|
||||
#{@activity.subject_params["event_title"]}
|
||||
</a>"
|
||||
}
|
||||
|
14
mix.lock
14
mix.lock
@ -16,7 +16,7 @@
|
||||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"credo": {:hex, :credo, "1.6.6", "f51f8d45db1af3b2e2f7bee3e6d3c871737bda4a91bff00c5eec276517d1a19c", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "625520ce0984ee0f9f1f198165cd46fa73c1e59a17ebc520038b8fce056a5bdc"},
|
||||
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
|
||||
"dataloader": {:hex, :dataloader, "1.0.10", "a42f07641b1a0572e0b21a2a5ae1be11da486a6790f3d0d14512d96ff3e3bbe9", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0 or ~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "54cd70cec09addf4b2ace14cc186a283a149fd4d3ec5475b155951bf33cd963f"},
|
||||
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
@ -62,7 +62,7 @@
|
||||
"geolix": {:hex, :geolix, "2.0.0", "7e65764bedfc98d08a3ddb24c417657c9d438eff163280b45fbb7de289626acd", [:mix], [], "hexpm", "8742bf588ed0bb7def2c443204d09d355990846c6efdff96ded66aac24c301df"},
|
||||
"geolix_adapter_mmdb2": {:hex, :geolix_adapter_mmdb2, "0.6.0", "6ab9dbf6ea395817aa1fd2597be25d0dda1853c7f664e62716e47728d18bc4f9", [:mix], [{:geolix, "~> 2.0", [hex: :geolix, repo: "hexpm", optional: false]}, {:mmdb2_decoder, "~> 3.0", [hex: :mmdb2_decoder, repo: "hexpm", optional: false]}], "hexpm", "06ff962feae8a310cffdf86b74bfcda6e2d0dccb439bb1f62df2b657b1c0269b"},
|
||||
"gettext": {:hex, :gettext, "0.20.0", "75ad71de05f2ef56991dbae224d35c68b098dd0e26918def5bb45591d5c8d429", [:mix], [], "hexpm", "1c03b177435e93a47441d7f681a7040bd2a816ece9e2666d1c9001035121eb3d"},
|
||||
"guardian": {:hex, :guardian, "2.2.4", "3dafdc19665411c96b2796d184064d691bc08813a132da5119e39302a252b755", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "6f83d4309c16ec2469da8606bb2a9815512cc2fac1595ad34b79940a224eb110"},
|
||||
"guardian": {:hex, :guardian, "2.3.0", "1e2a90e809fbd99439f5279db03fb30b7b2b2fc0d3870a0d76a84b099f1a2892", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "ced3ace74fc2b22b2b25dbe99e6d205443dd0d57d1cc25155a223b5e9656205e"},
|
||||
"guardian_db": {:hex, :guardian_db, "2.1.0", "ec95a9d99cdd1e550555d09a7bb4a340d8887aad0697f594590c2fd74be02426", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0 or ~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "f8e7d543ac92c395f3a7fd5acbe6829faeade57d688f7562e2f0fca8f94a0d70"},
|
||||
"guardian_phoenix": {:hex, :guardian_phoenix, "2.0.1", "89a817265af09a6ddf7cb1e77f17ffca90cea2db10ff888375ef34502b2731b1", [:mix], [{:guardian, "~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "21f439246715192b231f228680465d1ed5fbdf01555a4a3b17165532f5f9a08c"},
|
||||
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
|
||||
@ -74,7 +74,7 @@
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
|
||||
"ip_reserved": {:hex, :ip_reserved, "0.1.1", "e5112d71f1abf05207f82fd9597d369a5fde1e0b6d1bbe77c02a99bb26ecdc33", [:mix], [{:inet_cidr, "~> 1.0.0", [hex: :inet_cidr, repo: "hexpm", optional: false]}], "hexpm", "55fcd2b6e211caef09ea3f54ef37d43030bec486325d12fe865ab5ed8140a4fe"},
|
||||
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
|
||||
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
|
||||
"jose": {:hex, :jose, "1.11.2", "f4c018ccf4fdce22c71e44d471f15f723cb3efab5d909ab2ba202b5bf35557b3", [:mix, :rebar3], [], "hexpm", "98143fbc48d55f3a18daba82d34fe48959d44538e9697c08f34200fa5f0947d2"},
|
||||
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
|
||||
"junit_formatter": {:hex, :junit_formatter, "3.3.1", "c729befb848f1b9571f317d2fefa648e9d4869befc4b2980daca7c1edc468e40", [:mix], [], "hexpm", "761fc5be4b4c15d8ba91a6dafde0b2c2ae6db9da7b8832a55b5a1deb524da72b"},
|
||||
@ -97,10 +97,10 @@
|
||||
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
|
||||
"oauth2": {:hex, :oauth2, "2.0.1", "70729503e05378697b958919bb2d65b002ba6b28c8112328063648a9348aaa3f", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "c64e20d4d105bcdbcbe03170fb530d0eddc3a3e6b135a87528a22c8aecf74c52"},
|
||||
"oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"},
|
||||
"oban": {:hex, :oban, "2.13.2", "878e1296b47bad2027ca5dbe69f7547fa0d83cab81faf41aec421944f157b342", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21a0aa631722bb6c969079ff14acf5d3fa7b6bc547f363c8834f43b2c9cd654a"},
|
||||
"oban": {:hex, :oban, "2.13.3", "57c80ceb75489e126218b8a82ec5e4fee01b6588a81b566650bb8167db4111f3", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "8e997bddae17ec92bd12293f8b44f252f2f92ec03c54826390d1237a51ea47b2"},
|
||||
"paasaa": {:hex, :paasaa, "0.6.0", "07c8ed81010caa25db351d474f0c053072c809821c60f9646f7b1547bec52f6d", [:mix], [], "hexpm", "732ddfc21bac0831edb26aec468af3ec2b8997d74f6209810b1cc53199c29f2e"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"phoenix": {:hex, :phoenix, "1.6.11", "29f3c0fd12fa1fc4d4b05e341578e55bc78d96ea83a022587a7e276884d397e4", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1664e34f80c25ea4918fbadd957f491225ef601c0e00b4e644b1a772864bfbc2"},
|
||||
"phoenix": {:hex, :phoenix, "1.6.12", "f8f8ac077600f84419806dd53114b2e77aedde7a502e74181a7d886355aa0643", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d6cf5583c9c20f7103c40e6014ef802d96553b8e5d6585ad6e627bd5ddb0d12"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
|
||||
@ -124,13 +124,13 @@
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||
"struct_access": {:hex, :struct_access, "1.1.2", "a42e6ceedd9b9ea090ee94a6da089d56e16f374dbbc010c3eebdf8be17df286f", [:mix], [], "hexpm", "e4c411dcc0226081b95709909551fc92b8feb1a3476108348ea7e3f6c12e586a"},
|
||||
"sweet_xml": {:hex, :sweet_xml, "0.7.3", "debb256781c75ff6a8c5cbf7981146312b66f044a2898f453709a53e5031b45b", [:mix], [], "hexpm", "e110c867a1b3fe74bfc7dd9893aa851f0eed5518d0d7cad76d7baafd30e4f5ba"},
|
||||
"swoosh": {:hex, :swoosh, "1.7.4", "f967d9b2659e81bab241b96267aae1001d35c2beea2df9c03dcf47b007bf566f", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1553d994b4cf069162965e63de1e1c53d8236e127118d21e56ce2abeaa3f25b4"},
|
||||
"swoosh": {:hex, :swoosh, "1.8.0", "51b3cfe5bb08196eba0f64b0e30f589533915b5088dd203fde110f29704289db", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fd77341d3e775a81fccfd26baacb9a47328ac8c27df0fb1d06f0312306721472"},
|
||||
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
|
||||
"tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"},
|
||||
"timex": {:hex, :timex, "3.7.9", "790cdfc4acfce434e442f98c02ea6d84d0239073bfd668968f82ac63e9a6788d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "64691582e5bb87130f721fc709acfb70f24405833998fabf35be968984860ce1"},
|
||||
"tz_world": {:hex, :tz_world, "1.1.0", "af078ccbc63b618912d05a18402abf450252535a086e5a5e5189b54b710e5653", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:geo, "~> 1.0 or ~> 2.0 or ~> 3.3", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8e0a89a8e00968e0260f3176cab03c8960393cc10990ad10622d9eceb7ccfbe6"},
|
||||
"tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.10.2", "6e3b17d48c1cb7d5b2bca1255e908d49edf6150c622e5210ab3306acb84929aa", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "dfb7a5af57ed396341317b987815beace548f7deb33e760663546953b3f71c9d"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.10.3", "4a3bd7ab7b5d93d301d264f0f6858392654ee92171f4437d067d1ae227c051d9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "1394f36a6c64e97f2038cf95228e7e52b4cb75417962e30418fbe9902b30e6d3"},
|
||||
"ueberauth_cas": {:hex, :ueberauth_cas, "2.3.1", "df45a1f2c5df8bc80191cbca4baeeed808d697702ec5ebe5bd5d5a264481752f", [:mix], [{:httpoison, "~> 1.8", [hex: :httpoison, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "5068ae2b9e217c2f05aa9a67483a6531e21ba0be9a6f6c8749bb7fd1599be321"},
|
||||
"ueberauth_discord": {:hex, :ueberauth_discord, "0.7.0", "463f6dfe1ed10a76739331ce8e1dd3600ab611f10524dd828eb3aa50e76e9d43", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "d6f98ef91abb4ddceada4b7acba470e0e68c4d2de9735ff2f24172a8e19896b4"},
|
||||
"ueberauth_facebook": {:hex, :ueberauth_facebook, "0.10.0", "0d607fbd1b7c6e0449981571027d869c2d156b8ad20c42e3672346678c05ccf1", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "bf8ce5d66b1c50da8abff77e8086c1b710bdde63f4acaef19a651ba43a9537a8"},
|
||||
|
Loading…
Reference in New Issue
Block a user