Merge branch 'fixes' into 'main'

Various fixes

Closes #1321

See merge request framasoft/mobilizon!1448
This commit is contained in:
Thomas Citharel 2023-09-06 08:24:39 +00:00
commit 1c1afcb069
12 changed files with 97 additions and 97 deletions

View file

@ -392,6 +392,9 @@ config :mobilizon, Mobilizon.Service.GlobalSearch.SearchMobilizon,
config :mobilizon, Mobilizon.Service.AntiSpam, service: Mobilizon.Service.AntiSpam.Akismet config :mobilizon, Mobilizon.Service.AntiSpam, service: Mobilizon.Service.AntiSpam.Akismet
config :mobilizon, Mobilizon.Service.SiteMap,
path: System.get_env("MOBILIZON_SITEMAP_PATH", "/var/lib/mobilizon/sitemap")
# Import environment specific config. This must remain at the bottom # Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above. # of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs" import_config "#{config_env()}.exs"

View file

@ -92,6 +92,9 @@ config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "uploads"
config :mobilizon, :exports, path: "uploads/exports" config :mobilizon, :exports, path: "uploads/exports"
config :mobilizon, Mobilizon.Service.SiteMap,
path: System.get_env("MOBILIZON_SITEMAP_PATH", "priv/static")
config :tz_world, data_dir: "_build/dev/lib/tz_world/priv" config :tz_world, data_dir: "_build/dev/lib/tz_world/priv"
config :mobilizon, :anonymous, config :mobilizon, :anonymous,

View file

@ -62,6 +62,9 @@ config :mobilizon, Mobilizon.Web.Upload.Uploader.Local, uploads: "test/uploads"
config :mobilizon, :exports, path: "test/uploads/exports" config :mobilizon, :exports, path: "test/uploads/exports"
config :mobilizon, Mobilizon.Service.SiteMap,
path: System.get_env("MOBILIZON_SITEMAP_PATH", "test/sitemap")
config :tz_world, data_dir: "_build/test/lib/tz_world/priv" config :tz_world, data_dir: "_build/test/lib/tz_world/priv"
config :tesla, Mobilizon.Service.HTTP.ActivityPub, config :tesla, Mobilizon.Service.HTTP.ActivityPub,

View file

@ -1,4 +1,4 @@
FROM elixir as build FROM elixir:1.15 as build
SHELL ["/bin/bash", "-c"] SHELL ["/bin/bash", "-c"]
ENV MIX_ENV prod ENV MIX_ENV prod
# ENV LANG en_US.UTF-8 # ENV LANG en_US.UTF-8
@ -12,7 +12,7 @@ ENV ERL_FLAGS=$ERL_FLAGS
# Set the right versions # Set the right versions
ENV ELIXIR_VERSION latest ENV ELIXIR_VERSION latest
ENV ERLANG_VERSION latest ENV ERLANG_VERSION latest
ENV NODE_VERSION 16 ENV NODE_VERSION 18
# Install system dependencies # Install system dependencies
RUN apt-get update -yq && apt-get install -yq build-essential cmake postgresql-client git curl gnupg unzip exiftool webp imagemagick gifsicle RUN apt-get update -yq && apt-get install -yq build-essential cmake postgresql-client git curl gnupg unzip exiftool webp imagemagick gifsicle

View file

@ -10,7 +10,7 @@ RUN yarn install --network-timeout 100000 \
&& yarn run build && yarn run build
# Then, build the application binary # Then, build the application binary
FROM elixir:1.14-alpine AS builder FROM elixir:1.15-alpine AS builder
# Fix qemu segfault on arm64 # Fix qemu segfault on arm64
# See https://github.com/plausible/analytics/pull/2879 and https://github.com/erlang/otp/pull/6340 # See https://github.com/plausible/analytics/pull/2879 and https://github.com/erlang/otp/pull/6340

View file

@ -3,7 +3,7 @@
set -e set -e
echo "-- Waiting for database..." echo "-- Waiting for database..."
while ! pg_isready -U ${MOBILIZON_DATABASE_USERNAME} -d postgres://${MOBILIZON_DATABASE_HOST}:5432/${MOBILIZON_DATABASE_DBNAME} -t 1; do while ! pg_isready -U ${MOBILIZON_DATABASE_USERNAME} -d postgres://${MOBILIZON_DATABASE_HOST}:${MOBILIZON_DATABASE_PORT:-5432}/${MOBILIZON_DATABASE_DBNAME} -t 1; do
sleep 1s sleep 1s
done done

View file

@ -2,37 +2,32 @@ import { SEARCH_PERSONS } from "@/graphql/search";
import { VueRenderer } from "@tiptap/vue-3"; import { VueRenderer } from "@tiptap/vue-3";
import tippy from "tippy.js"; import tippy from "tippy.js";
import MentionList from "./MentionList.vue"; import MentionList from "./MentionList.vue";
import { apolloClient } from "@/vue-apollo"; import { apolloClient, waitApolloQuery } from "@/vue-apollo";
import { IPerson } from "@/types/actor"; import { IPerson } from "@/types/actor";
import pDebounce from "p-debounce"; import pDebounce from "p-debounce";
import { MentionOptions } from "@tiptap/extension-mention"; import { MentionOptions } from "@tiptap/extension-mention";
import { Editor } from "@tiptap/core"; import { Editor } from "@tiptap/core";
import { provideApolloClient, useQuery } from "@vue/apollo-composable"; import { provideApolloClient, useQuery } from "@vue/apollo-composable";
import { Paginate } from "@/types/paginate"; import { Paginate } from "@/types/paginate";
import { onError } from "@apollo/client/link/error";
const fetchItems = (query: string): Promise<IPerson[]> => { const fetchItems = async (query: string): Promise<IPerson[]> => {
return new Promise((resolve, reject) => { try {
const { onResult } = provideApolloClient(apolloClient)(() => { if (query === "") return [];
return useQuery<{ searchPersons: Paginate<IPerson> }>( const res = await waitApolloQuery(
SEARCH_PERSONS, provideApolloClient(apolloClient)(() => {
() => ({ return useQuery<
variables: { { searchPersons: Paginate<IPerson> },
{ searchText: string }
>(SEARCH_PERSONS, () => ({
searchText: query, searchText: query,
}, }));
}) })
); );
}); return res.data.searchPersons.elements;
} catch (e) {
onResult(({ data }) => { console.error(e);
resolve(data.searchPersons.elements); return [];
}); }
onError(reject);
});
// // TipTap doesn't handle async for onFilter, hence the following line.
// return result.data.searchPersons.elements;
}; };
const debouncedFetchItems = pDebounce(fetchItems, 200); const debouncedFetchItems = pDebounce(fetchItems, 200);
@ -68,6 +63,10 @@ const mentionOptions: MentionOptions = {
editor: props.editor, editor: props.editor,
}); });
if (!props.clientRect) {
return;
}
popup = tippy("body", { popup = tippy("body", {
getReferenceClientRect: props.clientRect, getReferenceClientRect: props.clientRect,
appendTo: () => document.body, appendTo: () => document.body,
@ -86,6 +85,12 @@ const mentionOptions: MentionOptions = {
}); });
}, },
onKeyDown(props: any) { onKeyDown(props: any) {
if (props.event.key === "Escape") {
popup[0].hide();
return true;
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
return component.ref?.onKeyDown(props); return component.ref?.onKeyDown(props);

View file

@ -1,8 +1,8 @@
<template> <template>
<div class="items"> <div class="relative border overflow-hidden dark:border-transparent">
<button <button
class="item" class="block w-full text-start bg-white dark:bg-violet-1 border py-1 px-2 rounded dark:border-transparent"
:class="{ 'is-selected': index === selectedIndex }" :class="{ 'border-black dark:!border-white': index === selectedIndex }"
v-for="(item, index) in items" v-for="(item, index) in items"
:key="index" :key="index"
@click="selectItem(index)" @click="selectItem(index)"
@ -34,37 +34,37 @@ watch(
} }
); );
// const onKeyDown = ({ event }: { event: KeyboardEvent }): boolean => { const onKeyDown = ({ event }: { event: KeyboardEvent }): boolean => {
// if (event.key === "ArrowUp") { if (event.key === "ArrowUp") {
// upHandler(); upHandler();
// return true; return true;
// } }
// if (event.key === "ArrowDown") { if (event.key === "ArrowDown") {
// downHandler(); downHandler();
// return true; return true;
// } }
// if (event.key === "Enter") { if (event.key === "Enter") {
// enterHandler(); enterHandler();
// return true; return true;
// } }
// return false; return false;
// }; };
// const upHandler = (): void => { const upHandler = (): void => {
// selectedIndex.value = selectedIndex.value =
// (selectedIndex.value + props.items.length - 1) % props.items.length; (selectedIndex.value + props.items.length - 1) % props.items.length;
// }; };
// const downHandler = (): void => { const downHandler = (): void => {
// selectedIndex.value = (selectedIndex.value + 1) % props.items.length; selectedIndex.value = (selectedIndex.value + 1) % props.items.length;
// }; };
// const enterHandler = (): void => { const enterHandler = (): void => {
// selectItem(selectedIndex.value); selectItem(selectedIndex.value);
// }; };
const selectItem = (index: number): void => { const selectItem = (index: number): void => {
const item = props.items[index]; const item = props.items[index];
@ -73,27 +73,8 @@ const selectItem = (index: number): void => {
props.command({ id: usernameWithDomain(item) }); props.command({ id: usernameWithDomain(item) });
} }
}; };
defineExpose({
onKeyDown,
});
</script> </script>
<style lang="scss" scoped>
.items {
position: relative;
border-radius: 0.25rem;
background: white;
color: rgba(black, 0.8);
overflow: hidden;
font-size: 0.9rem;
box-shadow:
0 0 0 1px rgba(0, 0, 0, 0.1),
0px 10px 20px rgba(0, 0, 0, 0.1);
}
.item {
display: block;
width: 100%;
text-align: left;
background: transparent;
border: none;
padding: 0.5rem 0.75rem;
}
</style>

View file

@ -657,4 +657,8 @@ onBeforeUnmount(() => {
.menubar__button.is-active { .menubar__button.is-active {
@apply bg-zinc-300 dark:bg-zinc-500; @apply bg-zinc-300 dark:bg-zinc-500;
} }
.mention[data-id] {
@apply inline-block border border-zinc-600 dark:border-zinc-300 rounded py-0.5 px-1;
}
</style> </style>

View file

@ -1,23 +1,20 @@
import { FILTER_TAGS } from "@/graphql/tags"; import { FILTER_TAGS } from "@/graphql/tags";
import { ITag } from "@/types/tag.model"; import { ITag } from "@/types/tag.model";
import { apolloClient } from "@/vue-apollo"; import { apolloClient, waitApolloQuery } from "@/vue-apollo";
import { provideApolloClient, useQuery } from "@vue/apollo-composable"; import { provideApolloClient, useQuery } from "@vue/apollo-composable";
export function fetchTags(text: string): Promise<ITag[]> { export async function fetchTags(text: string): Promise<ITag[]> {
return new Promise((resolve, reject) => { try {
const { onResult, onError } = provideApolloClient(apolloClient)(() => const res = await waitApolloQuery(
provideApolloClient(apolloClient)(() =>
useQuery<{ tags: ITag[] }, { filter: string }>(FILTER_TAGS, { useQuery<{ tags: ITag[] }, { filter: string }>(FILTER_TAGS, {
filter: text, filter: text,
}) })
)
); );
return res.data.tags;
onResult((result) => { } catch (e) {
if (result.loading) { console.error(e);
return; return [];
} }
return resolve(result.data.tags);
});
onError((error) => reject(error));
});
} }

View file

@ -620,4 +620,8 @@ useHead({
.event-description a { .event-description a {
@apply inline-block p-1 bg-mbz-yellow-alt-200 text-black; @apply inline-block p-1 bg-mbz-yellow-alt-200 text-black;
} }
.event-description .mention.h-card {
@apply inline-block border border-zinc-600 dark:border-zinc-300 rounded py-0.5 px-1;
}
</style> </style>

View file

@ -24,7 +24,7 @@ defmodule Mobilizon.Service.SiteMap do
config = [ config = [
store: Sitemapper.FileStore, store: Sitemapper.FileStore,
store_config: [path: Application.app_dir(:mobilizon, "priv/static")], store_config: [path: Application.get_env(:mobilizon, __MODULE__) |> get_in([:path])],
sitemap_url: Endpoint.url(), sitemap_url: Endpoint.url(),
gzip: false gzip: false
] ]