-
Notifications
You must be signed in to change notification settings - Fork 1
better mirrors page #426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
better mirrors page #426
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
2d13d2d
Replace status iframe with mirror cards and actions
ingoau a8f2a28
Update mirrors list
ingoau d7b15ff
add recommended badge
ingoau 58ef423
add gradient
ingoau c34b506
add backgorund to recommended
ingoau 9750c44
change colors a bit
ingoau 82ed1ca
Add more mirrors and improve quality badges on mirrors page
ingoau 9abbc24
add header
ingoau fc30f58
simplify
ingoau 194bec7
Highlight current mirror and hide actions for selected
ingoau 9ce9405
Remove localhost from mirrors list
ingoau d1ec78d
move mirrors to other file
ingoau 61f8879
Handle invalid mirror URLs gracefully in mirrors page
ingoau 3cb2e16
Handle migration errors and show toast notification
ingoau 5e589eb
Merge pull request #425 from EducationalTools/421-improve-mirrors-page
ingoau 7101527
Remove empty notes fields from mirrors config
ingoau 462c07d
reword dialog
ingoau File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,81 @@ | ||
| <iframe | ||
| src="https://educationaltools.github.io/status/" | ||
| title="Status" | ||
| frameborder="0" | ||
| class="h-full w-full" | ||
| ></iframe> | ||
| <script lang="ts"> | ||
| import Badge from '$lib/components/ui/badge/badge.svelte'; | ||
| import Button from '$lib/components/ui/button/button.svelte'; | ||
| import * as Card from '$lib/components/ui/card/index.js'; | ||
| import createBackup from '$lib/createBackup'; | ||
| import Trophy from '@lucide/svelte/icons/trophy'; | ||
| import Star from '@lucide/svelte/icons/star'; | ||
| import TriangleAlert from '@lucide/svelte/icons/triangle-alert'; | ||
| import { page } from '$app/state'; | ||
| import clsx from 'clsx'; | ||
| import type { Mirror } from './mirrors.config'; | ||
| import { mirrors } from './mirrors.config'; | ||
| import { toast } from 'svelte-sonner'; | ||
| </script> | ||
|
|
||
| <div class="mx-auto flex w-full max-w-3xl flex-col gap-3 p-3"> | ||
| <h1 class="text-3xl">Mirrors</h1> | ||
| <div class="grid w-full grid-cols-1 gap-3 md:grid-cols-2"> | ||
| {#each mirrors as mirror} | ||
| {@const selected = (() => { | ||
| try { | ||
| return page.url.hostname == new URL(mirror.url).hostname; | ||
| } catch (e) { | ||
| return false; | ||
| } | ||
| })()} | ||
| <Card.Root class={clsx(selected && 'bg-neutral-200 dark:bg-neutral-700')}> | ||
| <Card.Header> | ||
| <Card.Title> | ||
| {(() => { | ||
| try { | ||
| return new URL(mirror.url).hostname; | ||
| } catch (e) { | ||
| return 'Invalid URL'; | ||
| } | ||
| })()} | ||
| </Card.Title> | ||
|
|
||
| {#if selected} | ||
| <Badge variant="outline">Current</Badge> | ||
| {/if} | ||
| {#if mirror.quality == 'highlyrecommended'} | ||
| <Badge class="bg-gradient-to-r from-yellow-300 to-yellow-500" | ||
| ><Trophy />Highly Recommended</Badge | ||
| > | ||
| {:else if mirror.quality == 'recommended'} | ||
| <Badge class="bg-yellow-600 dark:bg-yellow-200"><Star />Recommended</Badge> | ||
| {:else if mirror.quality == 'notrecommended'} | ||
| <Badge class="bg-red-600 dark:bg-red-200"><TriangleAlert />Not Recommended</Badge> | ||
| {/if} | ||
|
|
||
| {#if mirror.notes} | ||
| <Card.Description>{mirror.notes}</Card.Description> | ||
| {/if} | ||
| </Card.Header> | ||
| {#if !selected} | ||
| <Card.Footer class="flex flex-row gap-3"> | ||
| <Button variant="outline" href={mirror.url}>Go</Button> | ||
| <Button | ||
| onclick={() => { | ||
| try { | ||
| const backup = createBackup(); | ||
| const url = new URL('/handoff', mirror.url); | ||
| url.searchParams.set('data', backup); | ||
| location.href = url.toString(); | ||
| } catch (error) { | ||
| console.error('Migration failed:', error); | ||
| toast.error('Migration failed'); | ||
| } | ||
| }} | ||
| > | ||
| Migrate | ||
| </Button> | ||
| </Card.Footer> | ||
| {/if} | ||
| </Card.Root> | ||
| {/each} | ||
| </div> | ||
| </div> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| export type Mirror = { | ||
| url: string; | ||
| quality?: 'highlyrecommended' | 'recommended' | 'notrecommended'; | ||
| notes?: string; | ||
| }; | ||
|
|
||
| export const mirrors: Mirror[] = [ | ||
| { url: 'https://edutools.ingo.au', quality: 'highlyrecommended' }, | ||
| { url: 'https://edutools.ingowolf.au', quality: 'recommended' }, | ||
| { url: 'https://educationaltools.github.io', quality: 'recommended' }, | ||
| { url: 'https://educationaltools.vercel.app' }, | ||
| { url: 'https://edutools-d915e.web.app' }, | ||
| { url: 'https://edutools-d915e.firebaseapp.com' }, | ||
| { url: 'https://edutools.infinityfreeapp.com', quality: 'notrecommended' } | ||
| ]; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify backup data size for URL parameter limitations.
Passing backup data via URL query parameters may hit browser URL length limits (typically 2048-8192 characters). Large backups could fail silently or be truncated.
Consider validating the backup size or using an alternative method for large data transfers:
Alternative approach for large backups:
onclick={() => { try { const backup = createBackup(); + // Check backup size before URL encoding + const encodedBackup = encodeURIComponent(backup); + if (encodedBackup.length > 2000) { + toast.error('Backup data too large for migration. Please export and import manually.'); + return; + } const url = new URL('/handoff', mirror.url); url.searchParams.set('data', backup); location.href = url.toString(); } catch (error) { console.error('Migration failed:', error); toast.error('Migration failed'); } }}🏁 Script executed:
Length of output: 201
🏁 Script executed:
Length of output: 263771
Implement Backup Size Handling Before URL Navigation
A review of
createBackup()usages insrc/routes/.../+page.svelteandsrc/lib/createBackup.tsshows no existing data‐size validation or URL‐length safeguards. Large backups risk exceeding browser URL limits, causing silent failures.Please add logic before
location.hrefto:encodeURIComponent(...))Example diff for
src/routes/mirrors/+page.svelte:onclick={() => { try { - const backup = createBackup(); + const backup = createBackup(); + const encoded = encodeURIComponent(backup); + if (encoded.length > 2000) { + toast.error('Backup too large for migration. Please export/import manually.'); + return; + } const url = new URL('/handoff', mirror.url); url.searchParams.set('data', backup); location.href = url.toString(); } catch (error) { console.error('Migration failed:', error); toast.error('Migration failed'); } }}Apply similar checks in all code paths that construct a migration URL.
📝 Committable suggestion
🤖 Prompt for AI Agents