tangled
alpha
login
or
join now
flo-bit.dev
/
blento
21
fork
atom
your personal website on atproto - mirror
blento.app
21
fork
atom
overview
issues
pulls
pipelines
first test
jycouet
1 month ago
0e4a4935
4feffd02
+68
-15
4 changed files
expand all
collapse all
unified
split
src
lib
cards
GitHubContributorsCard
GitHubContributorsCard.svelte
GitHubContributorsCardSettings.svelte
index.ts
routes
(auth)
oauth
callback
+page.svelte
+33
-13
src/lib/cards/GitHubContributorsCard/GitHubContributorsCard.svelte
···
13
13
let owner: string = $derived(item.cardData.owner ?? '');
14
14
let repo: string = $derived(item.cardData.repo ?? '');
15
15
let repoKey: string = $derived(owner && repo ? `${owner}/${repo}` : '');
16
16
+
let layout: 'hex' | 'grid' = $derived(item.cardData.layout ?? 'hex');
16
17
17
18
let serverContributors: GitHubContributor[] = $derived.by(() => {
18
19
if (!repoKey) return [];
···
66
67
const colsNarrow = Math.max(1, colsWide - 1);
67
68
const maxRows = Math.floor((availH + GAP) / (size + GAP));
68
69
let capacity = 0;
70
70
+
// Pattern: narrow, wide, narrow, wide... (row 0 is narrow)
69
71
for (let r = 0; r < maxRows; r++) {
70
70
-
capacity += r % 2 === 0 ? colsWide : colsNarrow;
72
72
+
capacity += r % 2 === 0 ? colsNarrow : colsWide;
71
73
}
72
74
return capacity;
73
75
}
74
76
77
77
+
function gridCapacity(size: number, availW: number, availH: number): number {
78
78
+
const cols = Math.floor((availW + GAP) / (size + GAP));
79
79
+
const rows = Math.floor((availH + GAP) / (size + GAP));
80
80
+
return cols * rows;
81
81
+
}
82
82
+
75
83
let computedSize = $derived.by(() => {
76
84
if (!containerWidth || !containerHeight || totalItems === 0) return 40;
77
85
78
86
let lo = MIN_SIZE;
79
87
let hi = MAX_SIZE;
88
88
+
const capacityFn = layout === 'hex' ? hexCapacity : gridCapacity;
80
89
81
90
while (lo <= hi) {
82
91
const mid = Math.floor((lo + hi) / 2);
83
83
-
const availW = containerWidth - mid;
84
84
-
const availH = containerHeight - mid;
92
92
+
const availW = containerWidth - (layout === 'hex' ? mid : 0);
93
93
+
const availH = containerHeight - (layout === 'hex' ? mid : 0);
85
94
if (availW <= 0 || availH <= 0) {
86
95
hi = mid - 1;
87
96
continue;
88
97
}
89
89
-
if (hexCapacity(mid, availW, availH) >= totalItems) {
98
98
+
if (capacityFn(mid, availW, availH) >= totalItems) {
90
99
lo = mid + 1;
91
100
} else {
92
101
hi = mid - 1;
···
96
105
return Math.max(MIN_SIZE, hi);
97
106
});
98
107
99
99
-
let padding = $derived(computedSize / 2);
108
108
+
let padding = $derived(layout === 'hex' ? computedSize / 2 : 0);
100
109
101
110
let rows = $derived.by(() => {
102
102
-
const availW = containerWidth - computedSize;
111
111
+
const availW = containerWidth - (layout === 'hex' ? computedSize : 0);
103
112
if (availW <= 0) return [] as GitHubContributor[][];
113
113
+
104
114
const colsWide = Math.floor((availW + GAP) / (computedSize + GAP));
105
105
-
const colsNarrow = Math.max(1, colsWide - 1);
115
115
+
const colsNarrow = layout === 'hex' ? Math.max(1, colsWide - 1) : colsWide;
106
116
117
117
+
// Calculate row sizes from bottom up, then reverse for incomplete row at top
118
118
+
const rowSizes: number[] = [];
119
119
+
let remaining = namedContributors.length;
120
120
+
let rowNum = 0;
121
121
+
while (remaining > 0) {
122
122
+
const cols = layout === 'hex' && rowNum % 2 === 0 ? colsNarrow : colsWide;
123
123
+
rowSizes.push(Math.min(cols, remaining));
124
124
+
remaining -= cols;
125
125
+
rowNum++;
126
126
+
}
127
127
+
rowSizes.reverse();
128
128
+
129
129
+
// Fill rows with contributors in order
107
130
const result: GitHubContributor[][] = [];
108
131
let idx = 0;
109
109
-
let rowNum = 0;
110
110
-
while (idx < namedContributors.length) {
111
111
-
const cols = rowNum % 2 === 0 ? colsWide : colsNarrow;
112
112
-
result.push(namedContributors.slice(idx, idx + cols));
113
113
-
idx += cols;
114
114
-
rowNum++;
132
132
+
for (const size of rowSizes) {
133
133
+
result.push(namedContributors.slice(idx, idx + size));
134
134
+
idx += size;
115
135
}
116
136
return result;
117
137
});
+32
src/lib/cards/GitHubContributorsCard/GitHubContributorsCardSettings.svelte
···
1
1
+
<script lang="ts">
2
2
+
import type { SettingsComponentProps } from '../types';
3
3
+
import { Label } from '@foxui/core';
4
4
+
5
5
+
let { item = $bindable() }: SettingsComponentProps = $props();
6
6
+
7
7
+
const layoutOptions = [
8
8
+
{ value: 'hex', label: 'Hexagon' },
9
9
+
{ value: 'grid', label: 'Grid' }
10
10
+
];
11
11
+
12
12
+
let layout = $derived(item.cardData.layout ?? 'hex');
13
13
+
</script>
14
14
+
15
15
+
<div class="flex flex-col gap-2">
16
16
+
<Label>Layout</Label>
17
17
+
<div class="flex gap-2">
18
18
+
{#each layoutOptions as opt (opt.value)}
19
19
+
<button
20
20
+
class={[
21
21
+
'flex-1 rounded-xl border px-3 py-2 text-sm transition-colors',
22
22
+
layout === opt.value
23
23
+
? 'bg-accent-500 border-accent-500 text-white'
24
24
+
: 'bg-base-100 dark:bg-base-800 border-base-300 dark:border-base-700 text-base-900 dark:text-base-100 hover:border-accent-400'
25
25
+
]}
26
26
+
onclick={() => (item.cardData.layout = opt.value)}
27
27
+
>
28
28
+
{opt.label}
29
29
+
</button>
30
30
+
{/each}
31
31
+
</div>
32
32
+
</div>
+2
src/lib/cards/GitHubContributorsCard/index.ts
···
1
1
import type { CardDefinition } from '../types';
2
2
import GitHubContributorsCard from './GitHubContributorsCard.svelte';
3
3
import CreateGitHubContributorsCardModal from './CreateGitHubContributorsCardModal.svelte';
4
4
+
import GitHubContributorsCardSettings from './GitHubContributorsCardSettings.svelte';
4
5
5
6
export type GitHubContributor = {
6
7
username: string;
···
15
16
type: 'githubContributors',
16
17
contentComponent: GitHubContributorsCard,
17
18
creationModalComponent: CreateGitHubContributorsCardModal,
19
19
+
settingsComponent: GitHubContributorsCardSettings,
18
20
createNew: (card) => {
19
21
card.w = 4;
20
22
card.h = 2;
+1
-2
src/routes/(auth)/oauth/callback/+page.svelte
···
12
12
goto('/' + getHandleOrDid(user.profile) + '/edit', {});
13
13
}
14
14
15
15
-
if(!user.isInitializing && !startedErrorTimer) {
15
15
+
if (!user.isInitializing && !startedErrorTimer) {
16
16
startedErrorTimer = true;
17
17
18
18
setTimeout(() => {
···
30
30
>There was an error signing you in, please go back to the
31
31
<a class="text-accent-600 dark:text-accent-400" href="/">homepage</a>
32
32
and try again.
33
33
-
34
33
</span>
35
34
</div>
36
35
{/if}