refactor: 🔥 Remove more old code

This commit is contained in:
Jesse Wierzbinski 2024-12-07 17:21:10 +01:00
parent 48196026ee
commit 9098720b49
No known key found for this signature in database
5 changed files with 0 additions and 312 deletions

View file

@ -1,39 +0,0 @@
<template>
<div v-bind="$attrs" class="bg-dark-700 overflow-hidden flex items-center justify-center">
<Skeleton :enabled="!imageLoaded" class="!h-full !w-full !rounded-none">
<img class="cursor-pointer ring-1 w-full h-full object-cover" :src="src" :alt="alt" />
</Skeleton>
</div>
</template>
<script lang="ts" setup>
import Skeleton from "../skeleton/Skeleton.vue";
defineOptions({
inheritAttrs: false,
});
const props = defineProps<{
src?: string;
alt?: string;
}>();
const imageLoaded = ref(false);
watch(
() => props.src,
(src) => {
if (!src) {
return;
}
// Load in background
const img = new Image();
img.src = src;
img.onload = () => {
imageLoaded.value = true;
};
},
{ immediate: true },
);
</script>

View file

@ -1,75 +0,0 @@
<template>
<div class="relative">
<textarea v-bind="$attrs" ref="textarea" v-model="content"
class="resize-none min-h-48 prose prose-invert w-full p-0 !ring-none !border-none !outline-none placeholder:text-zinc-500 bg-transparent appearance-none focus:!border-none focus:!outline-none disabled:cursor-not-allowed"
aria-label="Compose your message" :autofocus="true"></textarea>
<div v-if="maxCharacters"
:class="['absolute bottom-0 right-0 p-2 text-gray-300 font-semibold text-xs', remainingCharacters < 0 && 'text-red-500']"
aria-live="polite">
{{ remainingCharacters }}
</div>
<EmojiSuggestbox :textarea="textarea" v-if="!!currentlyBeingTypedEmoji"
:currently-typing-emoji="currentlyBeingTypedEmoji" @autocomplete="autocompleteEmoji" />
<MentionSuggestbox :textarea="textarea" v-if="!!currentlyBeingTypedMention"
:currently-typing-mention="currentlyBeingTypedMention" @autocomplete="autocompleteMention" />
</div>
</template>
<script lang="ts" setup>
import { char, createRegExp, exactly } from "magic-regexp";
import EmojiSuggestbox from "../composer-old/emoji-suggestbox.vue";
import MentionSuggestbox from "../composer-old/mention-suggestbox.vue";
defineOptions({
inheritAttrs: false,
});
const props = defineProps<{
maxCharacters?: number;
}>();
const modelContent = defineModel<string>("modelContent", {
required: true,
});
const textarea = ref<HTMLTextAreaElement | undefined>(undefined);
const { input: content } = useTextareaAutosize({
element: textarea,
input: modelContent,
});
const remainingCharacters = computed(
() =>
(props.maxCharacters ?? Number.POSITIVE_INFINITY) -
(content.value?.length ?? 0),
);
const currentlyBeingTypedEmoji = computed(() => {
const match = content.value?.match(partiallyTypedEmojiValidator);
return match ? (match.at(-1)?.replace(":", "") ?? "") : null;
});
const currentlyBeingTypedMention = computed(() => {
const match = content.value?.match(partiallyTypedMentionValidator);
return match ? (match.at(-1)?.replace("@", "") ?? "") : null;
});
const autocompleteEmoji = (emoji: string) => {
// Replace the end of the string with the emoji
content.value = content.value?.replace(
createRegExp(
exactly(":"),
exactly(currentlyBeingTypedEmoji.value ?? "").notBefore(char),
),
`:${emoji}:`,
);
};
const autocompleteMention = (mention: string) => {
// Replace the end of the string with the mention
content.value = content.value?.replace(
createRegExp(
exactly("@"),
exactly(currentlyBeingTypedMention.value ?? "").notBefore(char),
),
`@${mention} `,
);
};
</script>

View file

@ -1,16 +0,0 @@
<template>
<input :class="['block disabled:opacity-70 disabled:hover:cursor-wait w-full bg-dark-500 rounded-md border-0 py-1.5 text-gray-50 shadow-sm ring-1 ring-inset ring-white/10 placeholder:text-gray-500 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6',
isInvalid && '!ring-red-600 ring-2']" v-model="value">
</template>
<script setup lang="ts">
import type { InputHTMLAttributes } from "vue";
interface Props extends /* @vue-ignore */ InputHTMLAttributes {
isInvalid?: boolean;
}
const value = defineModel<string>("value");
defineProps<Props>();
</script>

View file

@ -1,125 +0,0 @@
<template>
<div
class="w-full md:px-8 px-4 py-4 grid justify-center lg:grid-cols-[minmax(auto,_36rem)_1fr] grid-cols-1 gap-4">
<form class="w-full ring-1 ring-inset ring-white/5 pb-5 bg-dark-800 rounded overflow-hidden"
@submit.prevent="save">
<Avatar :src="account?.header" :alt="`${account?.acct}'s header image'`"
class="w-full aspect-[8/3] border-b border-white/10 bg-dark-700 !rounded-none" />
<div class="flex items-start justify-between px-4 py-3">
<Avatar :src="account?.avatar" :alt="`${account?.acct}'s avatar'`"
class="h-32 w-32 -mt-[4.5rem] z-10 shrink-0 rounded ring-2 ring-dark-800" />
</div>
<div class="mt-2 px-4">
<TextInput @input="displayName = ($event.target as HTMLInputElement).value" :value="displayName"
aria-label="Display name" :disabled="loading" />
<div class="mt-2 grid grid-cols-[auto_1fr] items-center gap-x-2">
<iconify-icon icon="tabler:at" width="none" class="size-6" aria-hidden="true" />
<TextInput @input="acct = ($event.target as HTMLInputElement).value" :value="acct"
aria-label="Username" :disabled="loading" />
</div>
<p class="text-gray-300 text-xs mt-2">
Changing your username will break all links to your profile.
</p>
</div>
<div class="mt-3 px-4">
<RichTextboxInput v-model:model-content="note" :max-characters="bio" :disabled="loading"
class="rounded ring-white/10 ring-2 focus:ring-primary-600 px-4 py-2 max-h-[40dvh] max-w-full" />
</div>
<div class="px-4 mt-4 grid grid-cols-2 gap-2">
<Button theme="primary" class="w-full" type="submit" :loading="loading">
<span>Save</span>
</Button>
<Button theme="secondary" class="w-full" @click="revert" type="button" :loading="loading">
<span>Revert</span>
</Button>
</div>
</form>
<div>
<Oidc />
</div>
</div>
</template>
<script lang="ts" setup>
import type { ResponseError } from "@versia/client";
import Button from "~/packages/ui/components/buttons/button.vue";
import Avatar from "../avatars/avatar.vue";
import RichTextboxInput from "../inputs/rich-textbox-input.vue";
import TextInput from "../inputs/text-input.vue";
import Oidc from "./oidc.vue";
const account = computed(() => identity.value?.account);
const note = ref(account.value?.source?.note ?? "");
const displayName = ref(account.value?.display_name ?? "");
const acct = ref(account.value?.acct ?? "");
const bio = computed(
() => identity.value?.instance.configuration.statuses.max_characters ?? 0,
);
const loading = ref(false);
const revert = () => {
useEvent("notification:new", {
title: "Reverted to current bio",
type: "success",
});
note.value = account.value?.source?.note ?? "";
};
const save = async () => {
const changedData = {
display_name:
displayName.value === account.value?.display_name
? undefined
: displayName.value,
username: acct.value === account.value?.acct ? undefined : acct.value,
note:
note.value === account.value?.source?.note ? undefined : note.value,
};
if (
Object.values(changedData).filter((v) => v !== undefined).length === 0
) {
useEvent("notification:new", {
title: "No changes",
type: "error",
});
return;
}
loading.value = true;
try {
const { data } = await client.value.updateCredentials(
Object.fromEntries(
Object.entries(changedData).filter(([, v]) => v !== undefined),
),
);
useEvent("notification:new", {
title: "Profile updated",
type: "success",
});
if (identity.value) {
identity.value.account = data;
}
} catch (e) {
const error = e as ResponseError<{ error: string }>;
useEvent("notification:new", {
title: "Failed to update profile",
description: error.response.data.error,
type: "error",
});
}
loading.value = false;
};
</script>

View file

@ -1,57 +0,0 @@
<template>
<div v-for="index of lines" :class="[
'duration-200 animate-pulse bg-dark-100 [&:not(:first-child)]:mt-2',
shape === 'circle' ? 'rounded-full' : 'rounded',
['text', 'content'].includes(type) && 'h-[1em]',
props.class
]" v-if="enabled" :style="{
width: getWidth(index, lines),
}">
</div>
<slot v-else />
</template>
<script lang="ts" setup>
const props = withDefaults(
defineProps<{
enabled: boolean;
shape?: "circle" | "rect";
type?: "text" | "content";
minWidth?: number;
maxWidth?: number;
widthUnit?: "px" | "%";
class?: string;
lines?: number;
}>(),
{
shape: "rect",
type: "text",
widthUnit: "px",
},
);
const isContent = computed(() => props.type === "content");
const isText = computed(() => props.type === "text");
const isWidthSpecified = computed(() => props.minWidth && props.maxWidth);
const calculatedWidth = computed(
() =>
Math.random() * ((props.maxWidth ?? 0) - (props.minWidth ?? 0)) +
(props.minWidth ?? 0),
);
const getWidth = (index: number, lines: number) => {
if (isWidthSpecified.value) {
if (isContent.value) {
return index === lines
? `${calculatedWidth.value}${props.widthUnit}`
: "100%";
}
return `${calculatedWidth.value}${props.widthUnit}`;
}
return undefined;
};
const lines = isContent.value
? (props.lines ?? Math.ceil(Math.random() * 5))
: 1;
</script>