CRUD on defaultPicture & instanceFavicon settings. defaultPicture in UI.
TODO: instanceFavicon in UI.
This commit is contained in:
parent
c85d39a5aa
commit
0c668ef226
|
@ -267,7 +267,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
when is_admin(role) do
|
||||
with {:ok, res} <- Admin.save_settings("instance", args),
|
||||
with {:ok, res} <- Admin.save_settings("instance", IO.inspect(args, label: "SAVE_ARGS")),
|
||||
res <-
|
||||
res
|
||||
|> Enum.map(fn {key, val} ->
|
||||
|
@ -309,6 +309,18 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
get_media_setting(parent, %{group: "instance", name: "instance_logo"}, resolution)
|
||||
end
|
||||
|
||||
@spec get_instance_favicon(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t() | nil} | {:error, String.t()}
|
||||
def get_instance_favicon(parent, _args, resolution) do
|
||||
get_media_setting(parent, %{group: "instance", name: "instance_favicon"}, resolution)
|
||||
end
|
||||
|
||||
@spec get_default_picture(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t() | nil} | {:error, String.t()}
|
||||
def get_default_picture(parent, _args, resolution) do
|
||||
get_media_setting(parent, %{group: "instance", name: "default_picture"}, resolution)
|
||||
end
|
||||
|
||||
@spec update_user(any, map(), Absinthe.Resolution.t()) ::
|
||||
{:error, :invalid_argument | :user_not_found | binary | Ecto.Changeset.t()}
|
||||
| {:ok, Mobilizon.Users.User.t()}
|
||||
|
|
|
@ -35,10 +35,20 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
|||
end
|
||||
|
||||
@spec instance_logo(any(), map(), Absinthe.Resolution.t()) :: {:ok, Media.t()}
|
||||
def instance_logo(_parent, _locale, _resolution) do
|
||||
def instance_logo(_parent, _params, _resolution) do
|
||||
{:ok, MediaResolver.transform_media(Config.instance_logo())}
|
||||
end
|
||||
|
||||
@spec instance_favicon(any(), map(), Absinthe.Resolution.t()) :: {:ok, Media.t()}
|
||||
def instance_favicon(_parent, _params, _resolution) do
|
||||
{:ok, MediaResolver.transform_media(Config.instance_favicon())}
|
||||
end
|
||||
|
||||
@spec default_picture(any(), map(), Absinthe.Resolution.t()) :: {:ok, Media.t()}
|
||||
def default_picture(_parent, _params, _resolution) do
|
||||
{:ok, MediaResolver.transform_media(Config.default_picture())}
|
||||
end
|
||||
|
||||
@spec terms(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def terms(_parent, %{locale: locale}, _resolution) do
|
||||
type = Config.instance_terms_type()
|
||||
|
@ -107,6 +117,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
|||
slogan: Config.instance_slogan(),
|
||||
languages: Config.instance_languages(),
|
||||
instance_logo: Config.instance_logo(),
|
||||
instance_favicon: Config.instance_favicon(),
|
||||
default_picture: Config.default_picture(),
|
||||
anonymous: %{
|
||||
participation: %{
|
||||
allowed: Config.anonymous_participation?(),
|
||||
|
|
|
@ -128,6 +128,14 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||
description: "The instance's logo",
|
||||
resolve: &Admin.get_instance_logo/3
|
||||
)
|
||||
field(:instance_favicon, :media,
|
||||
description: "The instance's favicon",
|
||||
resolve: &Admin.get_instance_favicon/3
|
||||
)
|
||||
field(:default_picture, :media,
|
||||
description: "The default picture",
|
||||
resolve: &Admin.get_default_picture/3
|
||||
)
|
||||
|
||||
field(:instance_privacy_policy, :string,
|
||||
description: "The instance's privacy policy body text"
|
||||
|
@ -422,6 +430,14 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||
description:
|
||||
"The instance's logo, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
arg(:instance_favicon, :media_input,
|
||||
description:
|
||||
"The instance's favicon, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
arg(:default_picture, :media_input,
|
||||
description:
|
||||
"The default picture, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
|
||||
arg(:instance_terms, :string, description: "The instance's terms body text")
|
||||
arg(:instance_terms_type, :instance_terms_type, description: "The instance's terms type")
|
||||
|
|
|
@ -63,6 +63,14 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
|
|||
resolve(&Config.instance_logo/3)
|
||||
end
|
||||
|
||||
field(:instance_favicon, :media, description: "The instance's favicon") do
|
||||
resolve(&Config.instance_favicon/3)
|
||||
end
|
||||
|
||||
field(:default_picture, :media, description: "The default picture") do
|
||||
resolve(&Config.default_picture/3)
|
||||
end
|
||||
|
||||
field(:privacy, :privacy, description: "The instance's privacy policy") do
|
||||
arg(:locale, :string,
|
||||
default_value: "en",
|
||||
|
|
|
@ -180,7 +180,9 @@ defmodule Mobilizon.Admin do
|
|||
|
||||
@spec save_settings(String.t(), map()) :: {:ok, any} | {:error, any}
|
||||
def save_settings(group, args) do
|
||||
{medias, values} = Map.split(args, [:instance_logo])
|
||||
{medias, values} = Map.split(args, [:instance_logo, :instance_favicon, :default_picture])
|
||||
IO.inspect(medias, label: "MEDIAS")
|
||||
IO.inspect(values, label: "VALUES")
|
||||
|
||||
Multi.new()
|
||||
|> do_save_media_setting(group, medias)
|
||||
|
|
|
@ -79,17 +79,16 @@ defmodule Mobilizon.Config do
|
|||
def instance_slogan, do: config_cached_value("instance", "instance_slogan")
|
||||
|
||||
@spec instance_logo :: Media.t() | nil
|
||||
def instance_logo,
|
||||
do:
|
||||
config_cached_value(
|
||||
"instance",
|
||||
"instance_logo"
|
||||
)
|
||||
def instance_logo, do: config_cached_value( "instance", "instance_logo")
|
||||
|
||||
@spec instance_favicon :: Media.t() | nil
|
||||
def instance_favicon, do: config_cached_value( "instance", "instance_favicon")
|
||||
|
||||
@spec default_picture :: Media.t() | nil
|
||||
def default_picture, do: config_cached_value( "instance", "default_picture")
|
||||
|
||||
@spec contact :: String.t() | nil
|
||||
def contact do
|
||||
config_cached_value("instance", "contact")
|
||||
end
|
||||
def contact, do: config_cached_value("instance", "contact")
|
||||
|
||||
@spec instance_terms(String.t()) :: String.t()
|
||||
def instance_terms(locale \\ "en") do
|
||||
|
|
|
@ -169,6 +169,15 @@ type Config {
|
|||
"The instance's slogan"
|
||||
slogan: String
|
||||
|
||||
"The instance's logo"
|
||||
instanceLogo: Media
|
||||
|
||||
"The instance's favicon"
|
||||
instanceFavicon: Media
|
||||
|
||||
"The default picture"
|
||||
defaultPicture: Media
|
||||
|
||||
"The instance's contact details"
|
||||
contact: String
|
||||
|
||||
|
@ -1881,6 +1890,12 @@ type RootMutationType {
|
|||
"The instance's logo"
|
||||
instanceLogo: MediaInput
|
||||
|
||||
"The instance's favicon"
|
||||
instanceFavicon: MediaInput
|
||||
|
||||
"The default picture"
|
||||
defaultPicture: MediaInput
|
||||
|
||||
"The instance's terms body text"
|
||||
instanceTerms: String
|
||||
|
||||
|
@ -3702,7 +3717,13 @@ type AdminSettings {
|
|||
contact: String
|
||||
|
||||
"The instance's logo"
|
||||
instanceLogo: MediaInput
|
||||
instanceLogo: Media
|
||||
|
||||
"The instance's favicon"
|
||||
instanceFavicon: Media
|
||||
|
||||
"The default picture"
|
||||
defaultPicture: Media
|
||||
|
||||
"The instance's terms body text"
|
||||
instanceTerms: String
|
||||
|
|
|
@ -11,8 +11,11 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { IMedia } from "@/types/media.model";
|
||||
import { useDefaultPicture } from "@/composition/apollo/config";
|
||||
import LazyImage from "../Image/LazyImage.vue";
|
||||
|
||||
const { defaultPicture } = useDefaultPicture();
|
||||
|
||||
const DEFAULT_CARD_URL = "/img/mobilizon_default_card.png";
|
||||
const DEFAULT_BLURHASH = "MCHKI4El-P-U}+={R-WWoes,Iu-P=?R,xD";
|
||||
const DEFAULT_WIDTH = 630;
|
||||
|
@ -38,6 +41,9 @@ const props = withDefaults(
|
|||
|
||||
const pictureOrDefault = computed(() => {
|
||||
if (props.picture === null) {
|
||||
if (defaultPicture?.value?.url) {
|
||||
return defaultPicture.value;
|
||||
}
|
||||
return DEFAULT_PICTURE;
|
||||
}
|
||||
return {
|
||||
|
|
|
@ -4,11 +4,13 @@ import {
|
|||
ANONYMOUS_ACTOR_ID,
|
||||
ANONYMOUS_PARTICIPATION_CONFIG,
|
||||
ANONYMOUS_REPORTS_CONFIG,
|
||||
DEFAULT_PICTURE,
|
||||
DEMO_MODE,
|
||||
EVENT_CATEGORIES,
|
||||
EVENT_PARTICIPANTS,
|
||||
FEATURES,
|
||||
GEOCODING_AUTOCOMPLETE,
|
||||
INSTANCE_FAVICON,
|
||||
INSTANCE_LOGO,
|
||||
LOCATION,
|
||||
MAPS_TILES,
|
||||
|
@ -80,9 +82,7 @@ export function useInstanceName() {
|
|||
export function useInstanceLogoUrl() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "instanceLogo">;
|
||||
}>(INSTANCE_LOGO, {
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
}>(INSTANCE_LOGO);
|
||||
|
||||
const instanceLogoUrl = computed(
|
||||
() => result.value?.config?.instanceLogo?.url
|
||||
|
@ -90,6 +90,28 @@ export function useInstanceLogoUrl() {
|
|||
return { instanceLogoUrl, error, loading };
|
||||
}
|
||||
|
||||
export function useInstanceFaviconUrl() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "instanceFavicon">;
|
||||
}>(INSTANCE_FAVICON);
|
||||
|
||||
const instanceFaviconUrl = computed(
|
||||
() => result.value?.config?.instanceFavicon?.url
|
||||
);
|
||||
return { instanceFaviconUrl, error, loading };
|
||||
}
|
||||
|
||||
export function useDefaultPicture() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "defaultPicture">;
|
||||
}>(DEFAULT_PICTURE);
|
||||
|
||||
const defaultPicture = computed(
|
||||
() => result.value?.config?.defaultPicture
|
||||
);
|
||||
return { defaultPicture, error, loading };
|
||||
}
|
||||
|
||||
export function useAnonymousActorId() {
|
||||
const { result, error, loading } = useQuery<{
|
||||
config: Pick<IConfig, "anonymous">;
|
||||
|
|
|
@ -200,6 +200,16 @@ export const ADMIN_SETTINGS_FRAGMENT = gql`
|
|||
url
|
||||
name
|
||||
}
|
||||
instanceFavicon {
|
||||
id
|
||||
url
|
||||
name
|
||||
}
|
||||
defaultPicture {
|
||||
id
|
||||
url
|
||||
name
|
||||
}
|
||||
instanceTerms
|
||||
instanceTermsType
|
||||
instanceTermsUrl
|
||||
|
@ -229,6 +239,8 @@ export const SAVE_ADMIN_SETTINGS = gql`
|
|||
$instanceSlogan: String
|
||||
$contact: String
|
||||
$instanceLogo: MediaInput
|
||||
$instanceFavicon: MediaInput
|
||||
$defaultPicture: MediaInput
|
||||
$instanceTerms: String
|
||||
$instanceTermsType: InstanceTermsType
|
||||
$instanceTermsUrl: String
|
||||
|
@ -246,6 +258,8 @@ export const SAVE_ADMIN_SETTINGS = gql`
|
|||
instanceSlogan: $instanceSlogan
|
||||
contact: $contact
|
||||
instanceLogo: $instanceLogo
|
||||
instanceFavicon: $instanceFavicon
|
||||
defaultPicture: $defaultPicture
|
||||
instanceTerms: $instanceTerms
|
||||
instanceTermsType: $instanceTermsType
|
||||
instanceTermsUrl: $instanceTermsUrl
|
||||
|
|
|
@ -15,6 +15,19 @@ export const CONFIG = gql`
|
|||
instanceLogo {
|
||||
url
|
||||
}
|
||||
instanceFavicon {
|
||||
url
|
||||
}
|
||||
defaultPicture {
|
||||
id
|
||||
url
|
||||
name
|
||||
metadata {
|
||||
width
|
||||
height
|
||||
blurhash
|
||||
}
|
||||
}
|
||||
eventCategories {
|
||||
id
|
||||
label
|
||||
|
@ -169,9 +182,6 @@ export const ABOUT = gql`
|
|||
query About {
|
||||
config {
|
||||
name
|
||||
instanceLogo {
|
||||
url
|
||||
}
|
||||
description
|
||||
longDescription
|
||||
slogan
|
||||
|
@ -470,6 +480,33 @@ export const INSTANCE_LOGO = gql`
|
|||
}
|
||||
`;
|
||||
|
||||
export const INSTANCE_FAVICON = gql`
|
||||
query InstanceFavicon {
|
||||
config {
|
||||
instanceFavicon {
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const DEFAULT_PICTURE = gql`
|
||||
query DefaultPicture {
|
||||
config {
|
||||
defaultPicture {
|
||||
id
|
||||
url
|
||||
name
|
||||
metadata {
|
||||
width
|
||||
height
|
||||
blurhash
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const REGISTRATIONS = gql`
|
||||
query Registrations {
|
||||
config {
|
||||
|
|
|
@ -27,6 +27,8 @@ export interface IAdminSettings {
|
|||
instanceLongDescription: string;
|
||||
contact: string;
|
||||
instanceLogo: IMedia | null;
|
||||
instanceFavicon: IMedia | null;
|
||||
defaultPicture: IMedia | null;
|
||||
instanceTerms: string;
|
||||
instanceTermsType: InstanceTermsType;
|
||||
instanceTermsUrl: string | null;
|
||||
|
|
|
@ -38,6 +38,8 @@ export interface IConfig {
|
|||
contact: string;
|
||||
slogan: string;
|
||||
instanceLogo: { url: string };
|
||||
instanceFavicon: { url: string };
|
||||
defaultPicture: { url: string };
|
||||
|
||||
registrationsOpen: boolean;
|
||||
registrationsAllowlist: boolean;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type { Ref } from "vue";
|
||||
|
||||
export interface IMedia {
|
||||
id: string;
|
||||
url: string;
|
||||
|
@ -21,3 +23,9 @@ export interface IMediaMetadata {
|
|||
height?: number;
|
||||
blurhash?: string;
|
||||
}
|
||||
|
||||
export interface IModifiableMedia {
|
||||
file: Ref<File | null>
|
||||
firstHash: string | null
|
||||
hash: string | null
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { IMedia } from "@/types/media.model";
|
||||
import { IMedia, IModifiableMedia } from "@/types/media.model";
|
||||
import { ref, watch } from "vue";
|
||||
|
||||
export async function buildFileFromIMedia(
|
||||
obj: IMedia | null | undefined
|
||||
|
@ -45,9 +46,58 @@ export function readFileAsync(
|
|||
});
|
||||
}
|
||||
|
||||
export async function fileHash(file: File): Promise<ArrayBuffer | null> {
|
||||
export async function fileHash(file: File): Promise<string | null> {
|
||||
const data = await readFileAsync(file);
|
||||
if (data === null) return null;
|
||||
const hash = await crypto.subtle.digest("SHA-1", data);
|
||||
return hash;
|
||||
const b64Hash = btoa(Array.from(new Uint8Array(hash)).map(b => String.fromCharCode(b)).join(''))
|
||||
return b64Hash;
|
||||
}
|
||||
|
||||
export function initWrappedMedia(): IModifiableMedia {
|
||||
return {
|
||||
file: ref<File | null>(null),
|
||||
firstHash: null,
|
||||
hash: null,
|
||||
};
|
||||
}
|
||||
|
||||
export async function loadWrappedMedia(modifiableMedia: IModifiableMedia, media: IMedia | null) {
|
||||
watch(modifiableMedia.file, async () => {
|
||||
if (modifiableMedia.file.value) {
|
||||
modifiableMedia.hash = await fileHash(modifiableMedia.file.value);
|
||||
} else {
|
||||
modifiableMedia.hash = null;
|
||||
}
|
||||
});
|
||||
try {
|
||||
modifiableMedia.file.value = await buildFileFromIMedia(media);
|
||||
} catch (e) {
|
||||
console.error("catched error while building media", e);
|
||||
}
|
||||
if (modifiableMedia.file.value) {
|
||||
modifiableMedia.firstHash = await fileHash(modifiableMedia.file.value);
|
||||
}
|
||||
}
|
||||
|
||||
export function asMediaInput(mmedia: IModifiableMedia, name: string, fallbackId: number): any {
|
||||
let ret = {
|
||||
[name]: {},
|
||||
};
|
||||
if (mmedia.file.value) {
|
||||
if (mmedia.firstHash != mmedia.hash) {
|
||||
ret[name] = {
|
||||
media: {
|
||||
name: mmedia.file.value?.name,
|
||||
alt: "",
|
||||
file: mmedia.file.value,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
ret[name] = {
|
||||
mediaId: fallbackId
|
||||
};
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -58,8 +58,8 @@
|
|||
</small>
|
||||
<o-input v-model="settingsToWrite.contact" id="instance-contact" />
|
||||
</div>
|
||||
<div class="field flex flex-col">
|
||||
<label class="" for="instance-logo">{{ t("Logo") }}</label>
|
||||
<label class="field flex flex-col">
|
||||
<p>{{ t("Logo") }}</p>
|
||||
<small>
|
||||
{{ t("Logo of the instance. Defaults to the upstream Mobilizon logo.") }}
|
||||
</small>
|
||||
|
@ -69,7 +69,31 @@
|
|||
:textFallback="t('logo')"
|
||||
:maxSize="maxSize"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
<label class="field flex flex-col">
|
||||
<p>{{ t("Favicon") }}</p>
|
||||
<small>
|
||||
{{ t("Browser tab icon and PWA icon of the instance. Defaults to the upstream Mobilizon icon.") }}
|
||||
</small>
|
||||
<picture-upload
|
||||
v-model:modelValue="instanceFaviconFile"
|
||||
:defaultImage="settingsToWrite.instanceFavicon"
|
||||
:textFallback="t('favicon')"
|
||||
:maxSize="maxSize"
|
||||
/>
|
||||
</label>
|
||||
<label class="field flex flex-col">
|
||||
<p>{{ t("Default Picture") }}</p>
|
||||
<small>
|
||||
{{ t("Default picture when an event or group doesn't have one.") }}
|
||||
</small>
|
||||
<picture-upload
|
||||
v-model:modelValue="defaultPictureFile"
|
||||
:defaultImage="settingsToWrite.defaultPicture"
|
||||
:textFallback="t('default picture')"
|
||||
:maxSize="maxSize"
|
||||
/>
|
||||
</label>
|
||||
<o-field :label="t('Allow registrations')">
|
||||
<o-switch v-model="settingsToWrite.registrationsOpen">
|
||||
<p
|
||||
|
@ -406,7 +430,7 @@ import type { Notifier } from "@/plugins/notifier";
|
|||
|
||||
// Media upload related
|
||||
import PictureUpload from "@/components/PictureUpload.vue";
|
||||
import { buildFileFromIMedia, fileHash } from "@/utils/image";
|
||||
import { initWrappedMedia, loadWrappedMedia, asMediaInput } from "@/utils/image";
|
||||
import { useDefaultMaxSize } from "@/composition/config";
|
||||
|
||||
const defaultAdminSettings: IAdminSettings = {
|
||||
|
@ -416,6 +440,8 @@ const defaultAdminSettings: IAdminSettings = {
|
|||
instanceLongDescription: "",
|
||||
contact: "",
|
||||
instanceLogo: null,
|
||||
instanceFavicon: null,
|
||||
defaultPicture: null,
|
||||
instanceTerms: "",
|
||||
instanceTermsType: InstanceTermsType.DEFAULT,
|
||||
instanceTermsUrl: null,
|
||||
|
@ -441,29 +467,18 @@ onAdminSettingsResult(async ({ data }) => {
|
|||
adminSettings.value = {
|
||||
...data.adminSettings,
|
||||
} ?? defaultAdminSettings;
|
||||
if (adminSettings.value.instanceLogo) {
|
||||
try {
|
||||
instanceLogoFile.value = await buildFileFromIMedia(adminSettings.value.instanceLogo);
|
||||
instanceLogoServerHash.value = await fileHash(instanceLogoFile.value);
|
||||
} catch (e) {
|
||||
// Catch errors while building media
|
||||
console.error("catched error while building media", e);
|
||||
}
|
||||
}
|
||||
|
||||
loadWrappedMedia(instanceLogo, adminSettings.value.instanceLogo);
|
||||
loadWrappedMedia(instanceFavicon, adminSettings.value.instanceFavicon);
|
||||
loadWrappedMedia(defaultPicture, adminSettings.value.defaultPicture);
|
||||
});
|
||||
|
||||
let instanceLogoFile = ref<File | null>(null);
|
||||
let instanceLogoServerHash = ref<ArrayBuffer | null>(null);
|
||||
let instanceLogoHash = ref<ArrayBuffer | null>(null);
|
||||
|
||||
watch(instanceLogoFile, async () => {
|
||||
console.debug("LOGOFILECHANGED", instanceLogoFile);
|
||||
if (instanceLogoFile.value) {
|
||||
instanceLogoHash = await fileHash(instanceLogoFile.value);
|
||||
} else {
|
||||
instanceLogoHash = null;
|
||||
}
|
||||
});
|
||||
const instanceLogo = initWrappedMedia();
|
||||
const { file: instanceLogoFile } = instanceLogo;
|
||||
const instanceFavicon = initWrappedMedia();
|
||||
const { file: instanceFaviconFile } = instanceFavicon;
|
||||
const defaultPicture = initWrappedMedia();
|
||||
const { file: defaultPictureFile } = defaultPicture;
|
||||
|
||||
const { result: languageResult } = useQuery<{ languages: ILanguage[] }>(
|
||||
LANGUAGES
|
||||
|
@ -512,7 +527,9 @@ const {
|
|||
} = useMutation(SAVE_ADMIN_SETTINGS);
|
||||
|
||||
saveAdminSettingsDone(() => {
|
||||
instanceLogoServerHash = instanceLogoHash;
|
||||
instanceLogo.firstHash = instanceLogo.hash;
|
||||
instanceFavicon.firstHash = instanceFavicon.hash;
|
||||
defaultPicture.firstHash = defaultPicture.hash;
|
||||
notifier?.success(t("Admin settings successfully saved.") as string);
|
||||
});
|
||||
|
||||
|
@ -522,30 +539,12 @@ saveAdminSettingsError((e) => {
|
|||
});
|
||||
|
||||
const updateSettings = async (): Promise<void> => {
|
||||
console.debug("FILE AT UPDATE", instanceLogoFile.value);
|
||||
let instanceLogoObj = {
|
||||
instanceLogo: {},
|
||||
};
|
||||
if (instanceLogoFile.value) {
|
||||
if (instanceLogoServerHash != instanceLogoHash) {
|
||||
instanceLogoObj.instanceLogo = {
|
||||
media: {
|
||||
name: instanceLogoFile.value?.name,
|
||||
alt: "",
|
||||
file: instanceLogoFile.value,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
instanceLogoObj.instanceLogo = {
|
||||
mediaId: adminSettings.value?.instanceLogo?.id
|
||||
};
|
||||
}
|
||||
}
|
||||
const variables = {
|
||||
...settingsToWrite.value,
|
||||
...instanceLogoObj,
|
||||
...asMediaInput(instanceLogo, "instanceLogo", adminSettings.value?.instanceLogo?.id),
|
||||
...asMediaInput(instanceFavicon, "instanceFavicon", adminSettings.value?.instanceFavicon?.id),
|
||||
...asMediaInput(defaultPicture, "defaultPicture", adminSettings.value?.defaultPicture?.id),
|
||||
};
|
||||
console.debug("updating settings with variables", variables);
|
||||
saveAdminSettings(variables);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ module.exports = {
|
|||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#1e7d97",
|
||||
secondary: "#ffd599",
|
||||
primary: "var(--custom-primary, #1e7d97)",
|
||||
secondary: "var(--custom-secondary, #ffd599)",
|
||||
"violet-title": "#3c376e",
|
||||
tag: "rgb(var(--color-tag) / <alpha-value>)",
|
||||
"frama-violet": "#725794",
|
||||
|
|
Loading…
Reference in New Issue