Skip to content

Commit

Permalink
final commit
Browse files Browse the repository at this point in the history
  • Loading branch information
saboooor committed Dec 25, 2024
1 parent 5f4ba53 commit 1e2f44f
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 42 deletions.
73 changes: 54 additions & 19 deletions src/routes/resources/animtab/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { $, component$, useStore, useTask$, useVisibleTask$ } from '@builder.io/qwik';
import { $, component$, useSignal, useStore, useTask$, useVisibleTask$ } from '@builder.io/qwik';
import { routeLoader$, type DocumentHead } from '@builder.io/qwik-city';

import { defaults, loadPreset, types, v3formats, presets as presetlist } from '~/components/util/PresetUtils';
import { AnimationOutput, convertToHex, convertToRGB, getAnimFrames, getBrightness, getRandomColor } from '~/components/util/RGBUtils';

import { Add, BarChartOutline, ChevronDown, ChevronUp, ColorFillOutline, DiceOutline, DownloadOutline, GlobeOutline, LinkOutline, SaveOutline, SettingsOutline, ShareOutline, Text, TrashOutline } from 'qwik-ionicons';
import { Add, BarChartOutline, ChevronDown, ChevronUp, CloseOutline, ColorFillOutline, DiceOutline, DownloadOutline, GlobeOutline, LinkOutline, SaveOutline, SettingsOutline, ShareOutline, Text, TrashOutline } from 'qwik-ionicons';

import { Dropdown, Toggle, NumberInput, ColorPicker } from '@luminescent/ui-qwik';
import { inlineTranslate, useSpeak } from 'qwik-speak';
Expand Down Expand Up @@ -32,7 +32,7 @@ export const useCookies = routeLoader$(async ({ cookie, url }) => {
return {
animtab: animtabCookies,
rgb: rgbCookies,
presets: presetCookies.savedPresets || [],
presets: presetCookies,
};
});

Expand All @@ -45,6 +45,9 @@ export default component$(() => {
...structuredClone(rgbDefaults),
...cookies.rgb,
}, { deep: true });
const presetstore = useStore({
...cookies.presets,
});

const animtabstore = useStore({
...animTABDefaults,
Expand Down Expand Up @@ -88,6 +91,8 @@ export default component$(() => {
store.colors = sortColors(newColors);
});

const modalRef = useSignal<HTMLDialogElement>();

// eslint-disable-next-line qwik/no-use-visible-task
useVisibleTask$(async () => {
let lastTime = performance.now();
Expand Down Expand Up @@ -633,7 +638,7 @@ export default component$(() => {
}, 2000);
}
} values={
cookies.presets.map((preset) => ({
presetstore.savedPresets.map((preset) => ({
name: <span class={{
'break-all font-mc tracking-tight': true,
}}>
Expand Down Expand Up @@ -667,22 +672,52 @@ export default component$(() => {
<GlobeOutline width="20" /> Browse
</a>
<button class="lum-btn" id="save" onClick$={() => {
const preset: Partial<typeof defaults> = { ...store };
(Object.keys(preset) as Array<keyof typeof defaults>).forEach(key => {
if (key != 'version' && JSON.stringify(preset[key]) === JSON.stringify(defaults[key as keyof typeof defaults])) delete preset[key];
});
navigator.clipboard.writeText(JSON.stringify(preset));
const alert = {
class: 'text-green-500',
text: 'color.exportedPreset@@Successfully exported preset to clipboard!',
};
tmpstore.alerts.push(alert);
setTimeout(() => {
tmpstore.alerts.splice(tmpstore.alerts.indexOf(alert), 1);
}, 2000);
modalRef.value?.showModal();
}}>
<SaveOutline width="20" /> {t('color.save@@Save')}
</button>
<dialog ref={modalRef} class="lum-bg-gray-800/20 lum-pad-equal-2xl shadow-lg backdrop-blur-xl rounded-lg relative max-w-lg w-full transform transition-transform duration-300 ease-out">
<div class="flex flex-col gap-3">
<h3 class="text-gray-50 text-xl font-semibold mb-4">
{t('color.savePreset@@Save Preset')}
</h3>

<input class="lum-input" id="presetname" placeholder={t('color.presetName@@Preset Name')} />

<div class="flex gap-2 justify-end">
<button class="lum-btn" onClick$={() => {
modalRef.value?.close();
}}>
<CloseOutline width="20" /> {t('color.cancel@@Cancel')}
</button>
<button class="lum-btn lum-bg-green-900 hover:lum-bg-green-800" id="save" onClick$={() => {
const presetnameinput = document.getElementById('presetname') as HTMLInputElement;
const preset: Partial<typeof defaults> = {
...store,
...animtabstore,
name: presetnameinput.value ?? 'Untitled',
};
(Object.keys(preset) as Array<keyof typeof defaults>).forEach(key => {
if (key != 'version' && JSON.stringify(preset[key]) === JSON.stringify(defaults[key as keyof typeof defaults])) delete preset[key];
});
if (presetstore.savedPresets.find(p => JSON.stringify(p) === JSON.stringify(preset))) return;
presetstore.savedPresets.push(preset);
setCookies('presets', presetstore);
modalRef.value?.close();
const alert = {
class: 'text-green-500',
text: 'color.savedPreset@@Successfully saved preset!',
};
tmpstore.alerts.push(alert);
setTimeout(() => {
tmpstore.alerts.splice(tmpstore.alerts.indexOf(alert), 1);
}, 2000);
}}>
<SaveOutline width="20" /> {t('color.save@@Save')}
</button>
</div>
</div>
</dialog>
</div>
</div>
<div class="flex flex-col gap-2">
Expand Down Expand Up @@ -730,7 +765,7 @@ export default component$(() => {
</div>
<div class="grid grid-cols-2 gap-2">
<button class="lum-btn lum-pad-sm" id="export" onClick$={() => {
const preset: Partial<typeof defaults> = { ...store };
const preset: Partial<typeof defaults> = { ...store, ...animtabstore };
(Object.keys(preset) as Array<keyof typeof defaults>).forEach(key => {
if (key != 'version' && JSON.stringify(preset[key]) === JSON.stringify(defaults[key as keyof typeof defaults])) delete preset[key];
});
Expand All @@ -749,7 +784,7 @@ export default component$(() => {
<button class="lum-btn lum-pad-sm" id="createurl" onClick$={() => {
const base_url = `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
const url = new URL(base_url);
const params: Partial<typeof defaults> = { ...store };
const params: Partial<typeof defaults> = { ...store, ...animtabstore };
(Object.entries(params) as Array<[keyof typeof defaults, any]>).forEach(([key, value]) => {
if (key == 'format' || key == 'colors') {
value = JSON.stringify(value);
Expand Down
68 changes: 51 additions & 17 deletions src/routes/resources/rgb/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { $, component$, useStore, useTask$ } from '@builder.io/qwik';
import { $, component$, useSignal, useStore, useTask$ } from '@builder.io/qwik';
import { routeLoader$, type DocumentHead } from '@builder.io/qwik-city';

import { Gradient } from '~/components/util/HexUtils';
import { defaults, loadPreset, v3formats, presets as presetlist } from '~/components/util/PresetUtils';
import { convertToHex, convertToRGB, generateOutput, getBrightness, getRandomColor } from '~/components/util/RGBUtils';

import { Add, BarChartOutline, ChevronDown, ChevronUp, ColorFillOutline, DiceOutline, DownloadOutline, GlobeOutline, LinkOutline, SaveOutline, SettingsOutline, ShareOutline, Text, TrashOutline } from 'qwik-ionicons';
import { Add, BarChartOutline, ChevronDown, ChevronUp, CloseOutline, ColorFillOutline, DiceOutline, DownloadOutline, GlobeOutline, LinkOutline, SaveOutline, SettingsOutline, ShareOutline, Text, TrashOutline } from 'qwik-ionicons';

import { Dropdown, Toggle, NumberInput, ColorPicker } from '@luminescent/ui-qwik';
import { inlineTranslate, useSpeak } from 'qwik-speak';
Expand All @@ -32,7 +32,7 @@ export const useCookies = routeLoader$(async ({ cookie, url }) => {
const presetCookies = await getCookies(cookie, 'presets') as { savedPresets: Partial<typeof defaults>[] };
return {
rgb: rgbCookies,
presets: presetCookies.savedPresets || [],
presets: presetCookies,
};
});

Expand All @@ -45,6 +45,9 @@ export default component$(() => {
...structuredClone(rgbDefaults),
...cookies.rgb,
}, { deep: true });
const presetstore = useStore({
...cookies.presets,
});

const tmpstore: {
opened: {
Expand Down Expand Up @@ -82,6 +85,8 @@ export default component$(() => {
store.colors = sortColors(newColors);
});

const modalRef = useSignal<HTMLDialogElement>();

useTask$(({ track }) => {
if (isBrowser) setCookies('rgb', store);
(Object.keys(store) as Array<keyof typeof store>).forEach((key) => {
Expand Down Expand Up @@ -574,7 +579,7 @@ export default component$(() => {
}, 2000);
}
} values={
cookies.presets.map((preset) => ({
presetstore.savedPresets.map((preset) => ({
name: <span class={{
'break-all font-mc tracking-tight': true,
}}>
Expand Down Expand Up @@ -608,22 +613,51 @@ export default component$(() => {
<GlobeOutline width="20" /> Browse
</a>
<button class="lum-btn" id="save" onClick$={() => {
const preset: Partial<typeof defaults> = { ...store };
(Object.keys(preset) as Array<keyof typeof defaults>).forEach(key => {
if (key != 'version' && JSON.stringify(preset[key]) === JSON.stringify(defaults[key as keyof typeof defaults])) delete preset[key];
});
navigator.clipboard.writeText(JSON.stringify(preset));
const alert = {
class: 'text-green-500',
text: 'color.exportedPreset@@Successfully exported preset to clipboard!',
};
tmpstore.alerts.push(alert);
setTimeout(() => {
tmpstore.alerts.splice(tmpstore.alerts.indexOf(alert), 1);
}, 2000);
modalRef.value?.showModal();
}}>
<SaveOutline width="20" /> {t('color.save@@Save')}
</button>
<dialog ref={modalRef} class="lum-bg-gray-800/20 lum-pad-equal-2xl shadow-lg backdrop-blur-xl rounded-lg relative max-w-lg w-full transform transition-transform duration-300 ease-out">
<div class="flex flex-col gap-3">
<h3 class="text-gray-50 text-xl font-semibold mb-4">
{t('color.savePreset@@Save Preset')}
</h3>

<input class="lum-input" id="presetname" placeholder={t('color.presetName@@Preset Name')} />

<div class="flex gap-2 justify-end">
<button class="lum-btn" onClick$={() => {
modalRef.value?.close();
}}>
<CloseOutline width="20" /> {t('color.cancel@@Cancel')}
</button>
<button class="lum-btn lum-bg-green-900 hover:lum-bg-green-800" id="save" onClick$={() => {
const presetnameinput = document.getElementById('presetname') as HTMLInputElement;
const preset: Partial<typeof defaults> = {
...store,
name: presetnameinput.value ?? 'Untitled',
};
(Object.keys(preset) as Array<keyof typeof defaults>).forEach(key => {
if (key != 'version' && JSON.stringify(preset[key]) === JSON.stringify(defaults[key as keyof typeof defaults])) delete preset[key];
});
if (presetstore.savedPresets.find(p => JSON.stringify(p) === JSON.stringify(preset))) return;
presetstore.savedPresets.push(preset);
setCookies('presets', presetstore);
modalRef.value?.close();
const alert = {
class: 'text-green-500',
text: 'color.savedPreset@@Successfully saved preset!',
};
tmpstore.alerts.push(alert);
setTimeout(() => {
tmpstore.alerts.splice(tmpstore.alerts.indexOf(alert), 1);
}, 2000);
}}>
<SaveOutline width="20" /> {t('color.save@@Save')}
</button>
</div>
</div>
</dialog>
</div>
</div>
<div class="flex flex-col gap-2">
Expand Down
8 changes: 2 additions & 6 deletions src/routes/resources/rgb/presets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default component$(() => {
});

const filteredPresets = (store.showSaved && store.savedPresets.length > 0 ? store.savedPresets : presets).filter((preset) =>
preset.name!.toLowerCase().includes(store.searchTerm.toLowerCase()),
(preset.name ?? 'Untitled').toLowerCase().includes(store.searchTerm.toLowerCase()),
);

return (
Expand Down Expand Up @@ -81,7 +81,7 @@ export default component$(() => {
}}>
{(() => {
const colors = sortColors(preset.colors ?? presets[0].colors).map((color) => ({ rgb: convertToRGB(color.hex), pos: color.pos }));
if (colors.length < 2) return preset.name;
if (colors.length < 2) return preset.name ?? 'Untitled';

const gradient = new Gradient(colors, Math.ceil((preset.name ?? 'Untitled').length));

Expand All @@ -97,10 +97,6 @@ export default component$(() => {
});
})()}
</h3>
<p class="flex items-center gap-1 text-gray-400">
<img src="/branding/icon.png" alt="Birdflop" class="w-8 h-8 rounded-full" />
Birdflop
</p>
</div>
</div>
<div class="hidden sm:flex gap-2 mt-2">
Expand Down

0 comments on commit 1e2f44f

Please sign in to comment.