Create more stickers.
This commit is contained in:
parent
7ef87daaeb
commit
905cc40fa1
7 changed files with 85 additions and 19 deletions
|
|
@ -2,28 +2,32 @@ import { onBeforeMount, ref } from 'vue'
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
import { type User } from '@/stores/sessionStore'
|
||||||
import {
|
import {
|
||||||
activist,
|
|
||||||
type Sticker as StickerType,
|
type Sticker as StickerType,
|
||||||
useStickersStore,
|
useStickersStore,
|
||||||
} from '@/stores/stickersStore'
|
} from '@/stores/stickersStore'
|
||||||
|
|
||||||
|
|
||||||
export function useSticker() {
|
export function useSticker(user: User) {
|
||||||
let sticker: Ref<StickerType> = ref<StickerType>(activist);
|
const stickersStore = useStickersStore();
|
||||||
|
const { create, getSticker } = stickersStore;
|
||||||
|
const s = create(user.username);
|
||||||
|
let sticker: Ref<StickerType> = ref<StickerType>(s);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
if (!("id" in route.params)) {
|
if (!("id" in route.params)) {
|
||||||
return sticker;
|
return sticker;
|
||||||
}
|
}
|
||||||
const id = ref<string>(route.params.id as string);
|
const id = ref<string>(route.params.id as string);
|
||||||
const stickersStore = useStickersStore();
|
|
||||||
const { getSticker } = stickersStore;
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
onBeforeMount(async () => {
|
||||||
|
if (!id.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
await stickersStore.fetch(id.value);
|
await stickersStore.fetch(id.value);
|
||||||
let sticker2 = getSticker(id.value);
|
let sticker2 = getSticker(id.value);
|
||||||
if (!sticker2) {
|
if (!sticker2) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
sticker.value = sticker2;
|
sticker.value = sticker2;
|
||||||
stickersStore.activeSticker = id.value
|
stickersStore.activeSticker = id.value
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ const router = createRouter({
|
||||||
title: 'Sticker Builder',
|
title: 'Sticker Builder',
|
||||||
},
|
},
|
||||||
name: 'stickerbuilder',
|
name: 'stickerbuilder',
|
||||||
path: `/stickerbuilder/${id}`,
|
path: `/stickerbuilder/${id}*`,
|
||||||
// TODO: Consider using /:id/edit
|
// TODO: Consider using /:id/edit
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { useUserStore } from '@/stores/userStore'
|
||||||
export interface User {
|
export interface User {
|
||||||
name: string,
|
name: string,
|
||||||
sticker_ids: string[],
|
sticker_ids: string[],
|
||||||
username: string | null,
|
username: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
const anonymous: User = {
|
const anonymous: User = {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { useUserStore } from '@/stores/userStore'
|
||||||
|
|
||||||
export interface Sticker {
|
export interface Sticker {
|
||||||
color: string,
|
color: string,
|
||||||
|
createdBy: string | null,
|
||||||
layout: string,
|
layout: string,
|
||||||
orgs: string[],
|
orgs: string[],
|
||||||
message1: string | null,
|
message1: string | null,
|
||||||
|
|
@ -18,6 +19,7 @@ export interface Sticker {
|
||||||
|
|
||||||
export const activist: Sticker = {
|
export const activist: Sticker = {
|
||||||
color: '888888',
|
color: '888888',
|
||||||
|
createdBy: null,
|
||||||
layout: 'layout1',
|
layout: 'layout1',
|
||||||
orgs: [],
|
orgs: [],
|
||||||
message1: 'I AM AN ACTIVIST',
|
message1: 'I AM AN ACTIVIST',
|
||||||
|
|
@ -28,13 +30,36 @@ export const activist: Sticker = {
|
||||||
id: '6dcd2dae-7be2-4f79-8b10-caeb379452fc',
|
id: '6dcd2dae-7be2-4f79-8b10-caeb379452fc',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const colors = [
|
||||||
|
'c9c918', 'abe11c', '8bf226',
|
||||||
|
'6afc37', '4bfd4c', '2ff665',
|
||||||
|
'18e780', '09d09a', '02b4b3',
|
||||||
|
'0395c9', '0d74d9', '1e54e3',
|
||||||
|
'3637e7', '541ee3', '740dd9',
|
||||||
|
'9503c9', 'b402b3', 'd0099a',
|
||||||
|
'e71880', 'f62f65', 'fd4b4c',
|
||||||
|
'fc6a37', 'f28b26', 'e1ab1c',
|
||||||
|
];
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
activeSticker: string | null; // id
|
activeSticker: string | null; // id
|
||||||
stickers: Sticker[];
|
stickers: Sticker[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function randomColor() {
|
||||||
|
return colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
}
|
||||||
|
|
||||||
export const useStickersStore = defineStore('stickers', {
|
export const useStickersStore = defineStore('stickers', {
|
||||||
actions: {
|
actions: {
|
||||||
|
create(username: string) {
|
||||||
|
const sticker = structuredClone(activist);
|
||||||
|
sticker.color = randomColor();
|
||||||
|
sticker.createdBy = username;
|
||||||
|
sticker.id = self.crypto.randomUUID();
|
||||||
|
this.stickers.push(sticker);
|
||||||
|
return sticker;
|
||||||
|
},
|
||||||
async fetch(id: string) {
|
async fetch(id: string) {
|
||||||
if (this.getSticker(id)) {
|
if (this.getSticker(id)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -75,6 +100,15 @@ export const useStickersStore = defineStore('stickers', {
|
||||||
return state.stickers.find((sticker: Sticker) => sticker.id === id)
|
return state.stickers.find((sticker: Sticker) => sticker.id === id)
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
getStickersCreatedBy: (state: State) => {
|
||||||
|
return (username: string | null | undefined): Sticker[] => {
|
||||||
|
if (!username) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return state.stickers
|
||||||
|
.filter((sticker: Sticker) => sticker.createdBy === username);
|
||||||
|
};
|
||||||
|
},
|
||||||
},
|
},
|
||||||
state: (): State => {
|
state: (): State => {
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,28 @@ const events = [{
|
||||||
<Sticker v-bind="stickersStore.getSticker(sticker_id)" />
|
<Sticker v-bind="stickersStore.getSticker(sticker_id)" />
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</Panel>
|
||||||
|
<Panel header="Stickers Created">
|
||||||
<Button
|
<Button
|
||||||
as="router-link"
|
as="router-link"
|
||||||
to="/sticker"
|
to="/stickerbuilder"
|
||||||
v-if="myPage">
|
v-if="myPage">
|
||||||
New sticker
|
New sticker
|
||||||
</Button>
|
</Button>
|
||||||
|
<div class="stickers">
|
||||||
|
<div v-for="sticker in stickersStore.getStickersCreatedBy(user?.username)">
|
||||||
|
<div class="stickerWrapper">
|
||||||
|
<RouterLink :to="{ name: 'sticker', params: { id: sticker.id }}">
|
||||||
|
<Sticker v-bind="sticker" />
|
||||||
|
</RouterLink>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
v-bind:disabled="sessionStore.isAnonymous"
|
||||||
|
v-if="sticker?.owner == null">
|
||||||
|
Claim
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Panel header="Metrics">
|
<Panel header="Metrics">
|
||||||
|
|
@ -151,7 +167,14 @@ const events = [{
|
||||||
}
|
}
|
||||||
.stickerWrapper {
|
.stickerWrapper {
|
||||||
background-color: #F2F2F2;
|
background-color: #F2F2F2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
.sticker {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@media (screen(sm)) {
|
||||||
|
zoom: 250%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,21 @@ import IconLayout3Vue from '@/components/layouts/IconLayout3.vue';
|
||||||
import IconLayout4Vue from '@/components/layouts/IconLayout4.vue';
|
import IconLayout4Vue from '@/components/layouts/IconLayout4.vue';
|
||||||
import Sticker from '@/components/Sticker.vue';
|
import Sticker from '@/components/Sticker.vue';
|
||||||
import { type Organization, useOrganization } from '@/queries/organization';
|
import { type Organization, useOrganization } from '@/queries/organization';
|
||||||
|
import { useSessionStore } from '@/stores/sessionStore';
|
||||||
import { useSticker } from '@/composables/sticker';
|
import { useSticker } from '@/composables/sticker';
|
||||||
import { activist, type Sticker as StickerType } from '@/stores/stickersStore';
|
import { activist, type Sticker as StickerType } from '@/stores/stickersStore';
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Handle when the user is anonymous
|
||||||
|
const sessionStore = useSessionStore();
|
||||||
|
|
||||||
const { state: orgs } = useOrganization();
|
const { state: orgs } = useOrganization();
|
||||||
const original = useSticker();
|
const original = useSticker(sessionStore.user);
|
||||||
let sticker = ref<StickerType>(activist);
|
let sticker = ref<StickerType>(activist);
|
||||||
const orgFilter = ref("");
|
const orgFilter = ref("");
|
||||||
|
|
||||||
// When the original sticker appears, copy it into a local coy.
|
// When the original sticker loads, copy it into a local copy
|
||||||
|
// for editing.
|
||||||
watch(original, (newValue) => {
|
watch(original, (newValue) => {
|
||||||
sticker.value = structuredClone(toRaw(newValue));
|
sticker.value = structuredClone(toRaw(newValue));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ function claimSticker() {
|
||||||
<style scoped>
|
<style scoped>
|
||||||
#StickerWrapper {
|
#StickerWrapper {
|
||||||
background-color: #DDD;
|
background-color: #DDD;
|
||||||
padding: 12px;
|
padding: 10px;
|
||||||
#Sticker {
|
#Sticker {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
@media (screen(sm)) {
|
@media (screen(sm)) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue