mirror of
https://github.com/gabehf/Koito.git
synced 2026-03-14 01:46:09 -07:00
feat: v0.0.10 (#23)
* feat: single SOT for themes + basic custom support * fix: adjust colors for yuu theme * feat: Allow loading of environment variables from file (#20) * feat: allow loading of environment variables from file * Panic if a file for an environment variable cannot be read * Use log.Fatalf + os.Exit instead of panic * fix: remove supurfluous call to os.Exit() --------- Co-authored-by: adaexec <nixos-git.s1pht@simplelogin.com> Co-authored-by: Gabe Farrell <90876006+gabehf@users.noreply.github.com> * chore: add pr test workflow * chore: changelog * feat: make all activity grids configurable * fix: adjust activity grid style * fix: make background gradient consistent size * revert: remove year from activity grid opts * style: adjust top item list min size to 200px * feat: add support for custom themes * fix: stabilized the order of top items * chore: update changelog * feat: native import & export * fix: use correct request body for alias requests * fix: clear input when closing edit modal * chore: changelog * docs: make endpoint clearer for some apps * feat: add ui and handler for export * fix: fix pr test workflow --------- Co-authored-by: adaexec <78047743+adaexec@users.noreply.github.com> Co-authored-by: adaexec <nixos-git.s1pht@simplelogin.com>
This commit is contained in:
parent
486f5d0269
commit
c16b557c21
51 changed files with 1754 additions and 866 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect } from "react";
|
||||
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Props {
|
||||
stepSetter: (value: string) => void;
|
||||
|
|
@ -15,18 +16,15 @@ export default function ActivityOptsSelector({
|
|||
currentRange,
|
||||
disableCache = false,
|
||||
}: Props) {
|
||||
const stepPeriods = ['day', 'week', 'month', 'year'];
|
||||
const rangePeriods = [105, 182, 365];
|
||||
const stepPeriods = ['day', 'week', 'month'];
|
||||
const rangePeriods = [105, 182, 364];
|
||||
const [collapsed, setCollapsed] = useState(true);
|
||||
|
||||
const stepDisplay = (str: string): string => {
|
||||
return str.split('_').map(w =>
|
||||
w.split('').map((char, index) =>
|
||||
index === 0 ? char.toUpperCase() : char).join('')
|
||||
).join(' ');
|
||||
};
|
||||
|
||||
const rangeDisplay = (r: number): string => {
|
||||
return `${r}`
|
||||
const setMenuOpen = (val: boolean) => {
|
||||
setCollapsed(val)
|
||||
if (!disableCache) {
|
||||
localStorage.setItem('activity_configuring_' + window.location.pathname.split('/')[1], String(!val));
|
||||
}
|
||||
}
|
||||
|
||||
const setStep = (val: string) => {
|
||||
|
|
@ -42,56 +40,66 @@ export default function ActivityOptsSelector({
|
|||
localStorage.setItem('activity_range_' + window.location.pathname.split('/')[1], String(val));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (!disableCache) {
|
||||
const cachedRange = parseInt(localStorage.getItem('activity_range_' + window.location.pathname.split('/')[1]) ?? '35');
|
||||
if (cachedRange) {
|
||||
rangeSetter(cachedRange);
|
||||
}
|
||||
if (cachedRange) rangeSetter(cachedRange);
|
||||
const cachedStep = localStorage.getItem('activity_step_' + window.location.pathname.split('/')[1]);
|
||||
if (cachedStep) {
|
||||
stepSetter(cachedStep);
|
||||
}
|
||||
if (cachedStep) stepSetter(cachedStep);
|
||||
const cachedConfiguring = localStorage.getItem('activity_configuring_' + window.location.pathname.split('/')[1]);
|
||||
if (cachedStep) setMenuOpen(cachedConfiguring !== "true");
|
||||
}
|
||||
}, []);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<div className="flex gap-2 items-center">
|
||||
<p>Step:</p>
|
||||
{stepPeriods.map((p, i) => (
|
||||
<div key={`step_selector_${p}`}>
|
||||
<button
|
||||
className={`period-selector ${p === currentStep ? 'color-fg' : 'color-fg-secondary'} ${i !== stepPeriods.length - 1 ? 'pr-2' : ''}`}
|
||||
onClick={() => setStep(p)}
|
||||
disabled={p === currentStep}
|
||||
>
|
||||
{stepDisplay(p)}
|
||||
</button>
|
||||
<span className="color-fg-secondary">
|
||||
{i !== stepPeriods.length - 1 ? '|' : ''}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="relative w-full">
|
||||
<button
|
||||
onClick={() => setMenuOpen(!collapsed)}
|
||||
className="absolute left-[75px] -top-9 text-muted hover:color-fg transition"
|
||||
title="Toggle options"
|
||||
>
|
||||
{collapsed ? <ChevronDown size={18} /> : <ChevronUp size={18} />}
|
||||
</button>
|
||||
|
||||
<div className="flex gap-2 items-center">
|
||||
<p>Range:</p>
|
||||
{rangePeriods.map((r, i) => (
|
||||
<div key={`range_selector_${r}`}>
|
||||
<button
|
||||
className={`period-selector ${r === currentRange ? 'color-fg' : 'color-fg-secondary'} ${i !== rangePeriods.length - 1 ? 'pr-2' : ''}`}
|
||||
onClick={() => setRange(r)}
|
||||
disabled={r === currentRange}
|
||||
>
|
||||
{rangeDisplay(r)}
|
||||
</button>
|
||||
<span className="color-fg-secondary">
|
||||
{i !== rangePeriods.length - 1 ? '|' : ''}
|
||||
</span>
|
||||
<div
|
||||
className={`overflow-hidden transition-[max-height,opacity] duration-250 ease ${
|
||||
collapsed ? 'max-h-0 opacity-0' : 'max-h-[100px] opacity-100'
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-wrap gap-4 mt-1 text-sm">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-muted">Step:</span>
|
||||
{stepPeriods.map((p) => (
|
||||
<button
|
||||
key={p}
|
||||
className={`px-1 rounded transition ${
|
||||
p === currentStep ? 'color-fg font-medium' : 'color-fg-secondary hover:color-fg'
|
||||
}`}
|
||||
onClick={() => setStep(p)}
|
||||
disabled={p === currentStep}
|
||||
>
|
||||
{p}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-muted">Range:</span>
|
||||
{rangePeriods.map((r) => (
|
||||
<button
|
||||
key={r}
|
||||
className={`px-1 rounded transition ${
|
||||
r === currentRange ? 'color-fg font-medium' : 'color-fg-secondary hover:color-fg'
|
||||
}`}
|
||||
onClick={() => setRange(r)}
|
||||
disabled={r === currentRange}
|
||||
>
|
||||
{r}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue