Compare commits
5 Commits
8627a7945e
...
570a823426
| Author | SHA1 | Date | |
|---|---|---|---|
| 570a823426 | |||
| 6dddcd4d7a | |||
| 69e158b871 | |||
| d857cce5dc | |||
| c2bbd7ad88 |
@@ -16,7 +16,7 @@ const parentPath = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const inHome = computed(() => {
|
const inHome = computed(() => {
|
||||||
return route.path == "/";
|
return route.path == "/" || route.path == "/stp";
|
||||||
});
|
});
|
||||||
|
|
||||||
const faces = [
|
const faces = [
|
||||||
@@ -47,10 +47,10 @@ const faces_string = faces.join(" ");
|
|||||||
<template>
|
<template>
|
||||||
<nav class="flex flex-row w-full h-fit border border-primary bg-bg_primary">
|
<nav class="flex flex-row w-full h-fit border border-primary bg-bg_primary">
|
||||||
<RouterLink class="bdr-2 bg-bg_primary" to="/" v-if="!inHome">
|
<RouterLink class="bdr-2 bg-bg_primary" to="/" v-if="!inHome">
|
||||||
<a>HOME</a>
|
<span>HOME</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<RouterLink class="bdr-2 bg-bg_primary" v-if="parentPath" :to="parentPath">
|
<RouterLink class="bdr-2 bg-bg_primary" v-if="parentPath" :to="parentPath">
|
||||||
<a>UP</a>
|
<span>UP</span>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<Headline class="border flex-1 max-w-full">
|
<Headline class="border flex-1 max-w-full">
|
||||||
<code class="whitespace-pre">{{ faces_string }}</code>
|
<code class="whitespace-pre">{{ faces_string }}</code>
|
||||||
|
|||||||
39
nginx/vue/src/components/text/InlineLink.vue
Normal file
39
nginx/vue/src/components/text/InlineLink.vue
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
href: { type: String, default: "" },
|
||||||
|
to: { type: String, default: "" },
|
||||||
|
target: { type: String, default: undefined },
|
||||||
|
rel: { type: String, default: undefined },
|
||||||
|
});
|
||||||
|
|
||||||
|
const computedRel = computed(() => {
|
||||||
|
if (props.rel !== undefined) return props.rel;
|
||||||
|
if (props.target === "_blank") return "noopener noreferrer";
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<RouterLink v-if="to" :to="to" class="inline-link">
|
||||||
|
<slot />
|
||||||
|
</RouterLink>
|
||||||
|
<a v-else :href="href" :target="target" :rel="computedRel" class="inline-link">
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.inline-link {
|
||||||
|
color: var(--primary);
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: italic;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-link:hover {
|
||||||
|
color: var(--tertiary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
href: { type: String, default: "" },
|
||||||
|
to: { type: String, default: "" },
|
||||||
|
target: { type: String, default: undefined },
|
||||||
|
rel: { type: String, default: undefined },
|
||||||
|
bare: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
const computedRel = computed(() => {
|
||||||
|
if (props.rel !== undefined) return props.rel;
|
||||||
|
if (props.target === "_blank") return "noopener noreferrer";
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<RouterLink v-if="to" :to="to" :class="{ link: !bare }">
|
||||||
|
<slot />
|
||||||
|
</RouterLink>
|
||||||
|
<a v-else :href="href" :target="target" :rel="computedRel" :class="{ link: !bare }">
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.link {
|
||||||
|
color: var(--primary);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link:hover {
|
||||||
|
color: var(--tertiary);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Button from "@/components/input/Button.vue";
|
|||||||
import { useMessagesStore } from "@/stores/messages";
|
import { useMessagesStore } from "@/stores/messages";
|
||||||
import { useAuthStore } from "@/stores/auth";
|
import { useAuthStore } from "@/stores/auth";
|
||||||
import Header from "@/components/text/Header.vue";
|
import Header from "@/components/text/Header.vue";
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
|
|
||||||
const messagesStore = useMessagesStore();
|
const messagesStore = useMessagesStore();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
@@ -79,7 +80,7 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-col flex min-h-0">
|
<div class="chat-root flex-col flex min-h-0">
|
||||||
<Header>Chat</Header>
|
<Header>Chat</Header>
|
||||||
<div ref="messagesContainer" class="flex flex-col flex-1 min-h-0 overflow-y-auto overflow-x-hidden p-2 min-w-0">
|
<div ref="messagesContainer" class="flex flex-col flex-1 min-h-0 overflow-y-auto overflow-x-hidden p-2 min-w-0">
|
||||||
<p v-for="message in messages" :key="message.id" class="break-words min-w-0 w-full">
|
<p v-for="message in messages" :key="message.id" class="break-words min-w-0 w-full">
|
||||||
@@ -88,13 +89,13 @@ onUnmounted(() => {
|
|||||||
v-for="(part, i) in parseMessageParts(message.text || '')"
|
v-for="(part, i) in parseMessageParts(message.text || '')"
|
||||||
:key="i"
|
:key="i"
|
||||||
>
|
>
|
||||||
<a
|
<Link
|
||||||
v-if="part.type === 'link'"
|
v-if="part.type === 'link'"
|
||||||
|
bare
|
||||||
:href="part.value"
|
:href="part.value"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="text-primary underline break-all"
|
class="text-primary underline break-all"
|
||||||
>{{ part.value }}</a
|
>{{ part.value }}</Link
|
||||||
>
|
>
|
||||||
<span v-else>{{ part.value }}</span>
|
<span v-else>{{ part.value }}</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -112,9 +113,9 @@ onUnmounted(() => {
|
|||||||
class="w-full max-w-full max-h-48 rounded block"
|
class="w-full max-w-full max-h-48 rounded block"
|
||||||
@loadedmetadata="scrollToBottom"
|
@loadedmetadata="scrollToBottom"
|
||||||
/>
|
/>
|
||||||
<a v-else :href="message.fileUrl" target="_blank" class="underline break-all">{{
|
<Link v-else bare :href="message.fileUrl" target="_blank" class="underline break-all">{{
|
||||||
message.fileUrl.split("/").pop()
|
message.fileUrl.split("/").pop()
|
||||||
}}</a>
|
}}</Link>
|
||||||
</template>
|
</template>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -139,3 +140,11 @@ onUnmounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
.chat-root {
|
||||||
|
max-height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useHomeDataStore } from "@/stores/homeData";
|
import { useHomeDataStore } from "@/stores/homeData";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import Header from "@/components/text/Header.vue";
|
import Header from "@/components/text/Header.vue";
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
|
|
||||||
const homeData = useHomeDataStore();
|
const homeData = useHomeDataStore();
|
||||||
const { gitFeed: feed, loaded } = storeToRefs(homeData);
|
const { gitFeed: feed, loaded } = storeToRefs(homeData);
|
||||||
@@ -18,9 +19,9 @@ const { gitFeed: feed, loaded } = storeToRefs(homeData);
|
|||||||
<div v-else-if="feed" class="flex-1 flex flex-col overflow-y-auto">
|
<div v-else-if="feed" class="flex-1 flex flex-col overflow-y-auto">
|
||||||
<h3>Last git activity</h3>
|
<h3>Last git activity</h3>
|
||||||
<img :src="feed.avatarUrl" alt="User avatar" class="avatar" />
|
<img :src="feed.avatarUrl" alt="User avatar" class="avatar" />
|
||||||
<a :href="feed.repoUrl">
|
<Link :href="feed.repoUrl">
|
||||||
<h3>repo: {{ feed.repoName }}</h3>
|
<h3>repo: {{ feed.repoName }}</h3>
|
||||||
</a>
|
</Link>
|
||||||
<p>Action: {{ feed.opType }}</p>
|
<p>Action: {{ feed.opType }}</p>
|
||||||
<p>Message: {{ feed.commitMessage }}</p>
|
<p>Message: {{ feed.commitMessage }}</p>
|
||||||
<small> {{ new Date(feed.createdAt).toLocaleString() }}</small>
|
<small> {{ new Date(feed.createdAt).toLocaleString() }}</small>
|
||||||
|
|||||||
@@ -1,20 +1,73 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import { ref } from "vue";
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
|
import ToggleHeader from "@/components/text/ToggleHeader.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
linkArr: {
|
items: {
|
||||||
type: Array,
|
type: Array,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
variant: {
|
||||||
|
type: String,
|
||||||
|
default: "list",
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const keys = ["name", "link"];
|
const show = ref(false);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a v-for="(row, rowIndex) in linkArr" :key="rowIndex" :href="row.link">
|
<div v-if="title" class="h-fit w-fit">
|
||||||
<p class="bdr-2 bg-bg_tertiary">
|
<ToggleHeader v-model="show" class="justify-between flex">
|
||||||
{{ row.name }}
|
{{ title }}
|
||||||
</p>
|
</ToggleHeader>
|
||||||
</a>
|
<template v-if="show">
|
||||||
|
<Link
|
||||||
|
v-if="variant === 'list'"
|
||||||
|
v-for="(item, i) in items"
|
||||||
|
:key="i"
|
||||||
|
:href="item.link"
|
||||||
|
>
|
||||||
|
<p class="bdr-2 bg-bg_tertiary">{{ item.name }}</p>
|
||||||
|
</Link>
|
||||||
|
<table v-else>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item in items" :key="item.id">
|
||||||
|
<th>{{ item.type }}</th>
|
||||||
|
<td v-if="item.link">
|
||||||
|
<Link :href="item.link">{{ item.name }}</Link>
|
||||||
|
</td>
|
||||||
|
<td v-else>{{ item.name }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<template v-else>
|
||||||
|
<template v-if="variant === 'list'">
|
||||||
|
<Link
|
||||||
|
v-for="(item, i) in items"
|
||||||
|
:key="i"
|
||||||
|
:href="item.link"
|
||||||
|
>
|
||||||
|
<p class="bdr-2 bg-bg_tertiary">{{ item.name }}</p>
|
||||||
|
</Link>
|
||||||
|
</template>
|
||||||
|
<table v-else>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="item in items" :key="item.id">
|
||||||
|
<th>{{ item.type }}</th>
|
||||||
|
<td v-if="item.link">
|
||||||
|
<Link :href="item.link">{{ item.name }}</Link>
|
||||||
|
</td>
|
||||||
|
<td v-else>{{ item.name }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
// Array will have the form
|
|
||||||
// [ {type: string, name: string, link?: string}]
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const keys = ["type", "name", "link"];
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr v-for="item in data" :key="item.id">
|
|
||||||
<th>{{ item.type }}</th>
|
|
||||||
<td v-if="item.link">
|
|
||||||
<a :href="item.link">{{ item.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td v-else>{{ item.name }}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</template>
|
|
||||||
@@ -46,3 +46,11 @@ onMounted(() => {
|
|||||||
setInterval(checkStream, 120000);
|
setInterval(checkStream, 120000);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
max-height: 150px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -29,3 +29,10 @@ setInterval(updateDateTime, 60000);
|
|||||||
<h1>{{ time }}</h1>
|
<h1>{{ time }}</h1>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
div {
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ function playFinishedSound() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-1 p-1 items-center">
|
<div class="timer-root flex flex-col gap-1 p-1 items-center">
|
||||||
<Header>Timer</Header>
|
<Header>Timer</Header>
|
||||||
<div v-if="finished && paused" class="flex flex-col">
|
<div v-if="finished && paused" class="flex flex-col">
|
||||||
<div class="flex flex-row p-2 place-content-around">
|
<div class="flex flex-row p-2 place-content-around">
|
||||||
@@ -113,3 +113,12 @@ function playFinishedSound() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
.timer-root {
|
||||||
|
padding: 2px;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import ToggleHeader from "@/components/text/ToggleHeader.vue";
|
|
||||||
|
|
||||||
import { ref } from "vue";
|
|
||||||
import LinkTable from "@/components/util/LinkTable.vue";
|
|
||||||
|
|
||||||
const props = defineProps({
|
|
||||||
linkArr: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const show_links = ref(false);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="h-fit w-fit">
|
|
||||||
<ToggleHeader v-model="show_links" class="justify-between flex"
|
|
||||||
>{{ title }}
|
|
||||||
</ToggleHeader>
|
|
||||||
<LinkTable v-if="show_links" :linkArr="props.linkArr" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
import { createRouter, createWebHistory } from "vue-router";
|
import { createRouter, createWebHistory } from "vue-router";
|
||||||
import Home from "@/views/home/Home.vue";
|
import Landing from "@/views/Landing.vue";
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
|
name: "landing",
|
||||||
|
component: Landing,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/stp",
|
||||||
name: "home",
|
name: "home",
|
||||||
component: Home,
|
component: () => import("@/views/home/Home.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/cv",
|
path: "/cv",
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from "vue";
|
import LinkTable from "@/components/util/LinkTable.vue";
|
||||||
|
|
||||||
import ToggleLinkTable from "@/components/util/ToggleLinkTable.vue";
|
|
||||||
|
|
||||||
const links = [
|
const links = [
|
||||||
[
|
[
|
||||||
@@ -245,11 +243,11 @@ const links = [
|
|||||||
class="a4page-portrait bdr-1 flex flex-row flex-wrap overflow-x-auto gap-1"
|
class="a4page-portrait bdr-1 flex flex-row flex-wrap overflow-x-auto gap-1"
|
||||||
>
|
>
|
||||||
<div class="w-full h-fit">
|
<div class="w-full h-fit">
|
||||||
<ToggleLinkTable
|
<LinkTable
|
||||||
class="flex flex-col flex-wrap"
|
class="flex flex-col flex-wrap"
|
||||||
v-for="link in links"
|
v-for="link in links"
|
||||||
:title="link[0]"
|
:title="link[0]"
|
||||||
:linkArr="link[1]"
|
:items="link[1]"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
56
nginx/vue/src/views/Landing.vue
Normal file
56
nginx/vue/src/views/Landing.vue
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<script setup>
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
|
import InlineLink from "@/components/text/InlineLink.vue";
|
||||||
|
import Header from "@/components/text/Header.vue";
|
||||||
|
import Paragraph from "@/components/text/Paragraph.vue";
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
{ name: "GitHub", href: "https://github.com/SteveThePug" },
|
||||||
|
{ name: "Gitea", href: "/gitea/explore/repos" },
|
||||||
|
{ name: "Spotify", href: "https://open.spotify.com/user/stevethepug" },
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<main class="halftone flex justify-center px-4 py-16">
|
||||||
|
<div class="max-w-xl w-full flex flex-col gap-12">
|
||||||
|
<section>
|
||||||
|
<Header>Adam French</Header>
|
||||||
|
<Paragraph>
|
||||||
|
Junior software engineer focused on full-stack development,
|
||||||
|
systems programming, and infrastructure. First Class Honours
|
||||||
|
in Computer Science with Mathematics from Leeds and
|
||||||
|
Waterloo.
|
||||||
|
</Paragraph>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<Header>About</Header>
|
||||||
|
<Paragraph>
|
||||||
|
This website is self-hosted and has a lot more on it than it
|
||||||
|
needs to. Please have a look at my
|
||||||
|
<InlineLink to="/cv">CV</InlineLink> for a full breakdown of
|
||||||
|
my experience, projects, and skills. Please visit
|
||||||
|
<InlineLink to="/stp">STP</InlineLink> for the prefered but
|
||||||
|
less professional experience.
|
||||||
|
</Paragraph>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<nav class="navRow flex flex-row flex-wrap gap-4 justify-around">
|
||||||
|
<Link to="/cv"> CV </Link>
|
||||||
|
<Link to="/stp"> STP </Link>
|
||||||
|
<Link href="mailto:adam.a.french@outlook.com"> Email </Link>
|
||||||
|
<Link v-for="link in links" :key="link.name" :href="link.href">
|
||||||
|
{{ link.name }}
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.navRow > a {
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border: 1px solid currentColor;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import AutoScroll from "@/components/util/AutoScroll.vue";
|
import AutoScroll from "@/components/util/AutoScroll.vue";
|
||||||
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
|
import LinkTable from "@/components/util/LinkTable.vue";
|
||||||
import Header from "@/components/text/Header.vue";
|
import Header from "@/components/text/Header.vue";
|
||||||
|
|
||||||
import { useActivityStore } from "@/stores/activity";
|
import { useActivityStore } from "@/stores/activity";
|
||||||
@@ -12,7 +12,7 @@ const activityStore = useActivityStore();
|
|||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<Header>Consumption</Header>
|
<Header>Consumption</Header>
|
||||||
<AutoScroll class="flex-1 w-full">
|
<AutoScroll class="flex-1 w-full">
|
||||||
<OptionalLinkTable class="w-full" :data="activityStore.activity" />
|
<LinkTable variant="table" class="w-full" :items="activityStore.activity" />
|
||||||
</AutoScroll>
|
</AutoScroll>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import Header from "@/components/text/Header.vue";
|
import Header from "@/components/text/Header.vue";
|
||||||
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
|
import LinkTable from "@/components/util/LinkTable.vue";
|
||||||
import AutoScroll from "@/components/util/AutoScroll.vue";
|
import AutoScroll from "@/components/util/AutoScroll.vue";
|
||||||
|
|
||||||
import { useFavoritesStore } from "@/stores/favorites";
|
import { useFavoritesStore } from "@/stores/favorites";
|
||||||
@@ -12,9 +12,10 @@ const favoritesStore = useFavoritesStore();
|
|||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<Header>favs</Header>
|
<Header>favs</Header>
|
||||||
<AutoScroll class="w-full flex-1">
|
<AutoScroll class="w-full flex-1">
|
||||||
<OptionalLinkTable
|
<LinkTable
|
||||||
|
variant="table"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
:data="favoritesStore.favorites"
|
:items="favoritesStore.favorites"
|
||||||
/>
|
/>
|
||||||
</AutoScroll>
|
</AutoScroll>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import Header from "@/components/text/Header.vue";
|
import Header from "@/components/text/Header.vue";
|
||||||
import OptionalLinkTable from "@/components/util/OptionalLinkTable.vue";
|
import LinkTable from "@/components/util/LinkTable.vue";
|
||||||
const gym = [
|
const gym = [
|
||||||
{ name: "Row", type: "30 min" },
|
{ name: "Row", type: "30 min" },
|
||||||
{ name: "Run", type: "5k" },
|
{ name: "Run", type: "5k" },
|
||||||
@@ -14,7 +14,7 @@ const gym = [
|
|||||||
<p>I'm not a gym geek</p>
|
<p>I'm not a gym geek</p>
|
||||||
<p>4/7 days I do:</p>
|
<p>4/7 days I do:</p>
|
||||||
<div class="overflow-scroll w-full border-box">
|
<div class="overflow-scroll w-full border-box">
|
||||||
<OptionalLinkTable class="w-full" :data="gym" />
|
<LinkTable variant="table" class="w-full" :items="gym" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import Consumption from "./Consumption.vue";
|
|||||||
>
|
>
|
||||||
<Chat class="flex-1 min-h-0" />
|
<Chat class="flex-1 min-h-0" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="sidebar-image">
|
||||||
<Miku class="border-tertiary border bg-bg_secondary" />
|
<Miku class="border-tertiary border bg-bg_secondary" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,7 +63,7 @@ import Consumption from "./Consumption.vue";
|
|||||||
<!-- <Elle class="flex-1" /> -->
|
<!-- <Elle class="flex-1" /> -->
|
||||||
<!-- <MusicPlayer /> -->
|
<!-- <MusicPlayer /> -->
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="sidebar-image">
|
||||||
<img
|
<img
|
||||||
src="/img/memes/fire-woman.gif"
|
src="/img/memes/fire-woman.gif"
|
||||||
class="border-tertiary border"
|
class="border-tertiary border"
|
||||||
@@ -122,14 +122,24 @@ import Consumption from "./Consumption.vue";
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
flex-direction: row;
|
display: grid;
|
||||||
flex-wrap: wrap;
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||||
justify-content: center;
|
gap: 8px;
|
||||||
|
justify-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar > * {
|
.sidebar > * {
|
||||||
max-width: 400px;
|
max-width: none;
|
||||||
width: 100%;
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-image {
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-image :deep(img) {
|
||||||
|
max-height: 200px;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const social_links = [
|
|||||||
<RouterTable :linkArr="site_links" />
|
<RouterTable :linkArr="site_links" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-1">
|
<div class="flex flex-col gap-1">
|
||||||
<LinkTable :linkArr="social_links" />
|
<LinkTable :items="social_links" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
import Touchscreen from "@/components/util/Touchscreen.vue";
|
import Touchscreen from "@/components/util/Touchscreen.vue";
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
import { shuffleArray } from "@/js/utils.js";
|
import { shuffleArray } from "@/js/utils.js";
|
||||||
|
|
||||||
let srcs = [
|
let srcs = [
|
||||||
@@ -23,15 +24,15 @@ shuffleArray(srcs);
|
|||||||
<template>
|
<template>
|
||||||
<Touchscreen>
|
<Touchscreen>
|
||||||
<div class="flex flex-wrap tst">
|
<div class="flex flex-wrap tst">
|
||||||
<a href="https://www.adam-french.co.uk">
|
<Link bare href="https://www.adam-french.co.uk">
|
||||||
<img src="https://www.adam-french.co.uk/img/stamps/mine.gif" />
|
<img src="https://www.adam-french.co.uk/img/stamps/mine.gif" />
|
||||||
</a>
|
</Link>
|
||||||
<a href="https://jacobbarron.xyz">
|
<Link bare href="https://jacobbarron.xyz">
|
||||||
<img
|
<img
|
||||||
src="https://jacobbarron.xyz/Banneh.gif"
|
src="https://jacobbarron.xyz/Banneh.gif"
|
||||||
alt="jacobbarron.xyz"
|
alt="jacobbarron.xyz"
|
||||||
/>
|
/>
|
||||||
</a>
|
</Link>
|
||||||
<img v-for="src in srcs" :src="src" />
|
<img v-for="src in srcs" :src="src" />
|
||||||
</div>
|
</div>
|
||||||
</Touchscreen>
|
</Touchscreen>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import VideoTable from "@/components/util/VideoTable.vue";
|
import VideoTable from "@/components/util/VideoTable.vue";
|
||||||
|
import Link from "@/components/text/Link.vue";
|
||||||
|
|
||||||
const videoSources = [
|
const videoSources = [
|
||||||
{ name: "demoman", link: "/img/demoman/1760582395316219.webm" },
|
{ name: "demoman", link: "/img/demoman/1760582395316219.webm" },
|
||||||
@@ -16,8 +17,8 @@ const videoSources = [
|
|||||||
class="a4page-portrait bdr-1 flex flex-row relative overflow-scroll items-center"
|
class="a4page-portrait bdr-1 flex flex-row relative overflow-scroll items-center"
|
||||||
>
|
>
|
||||||
<p>
|
<p>
|
||||||
<a href="https://wiki.teamfortress.com/wiki/Demoman"
|
<Link href="https://wiki.teamfortress.com/wiki/Demoman"
|
||||||
>The goat</a
|
>The goat</Link
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user