Skip to content

Commit f9c6704

Browse files
committed
add archive permalink page
1 parent 4aac8ce commit f9c6704

9 files changed

+109
-23
lines changed

main.go

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func setupServer(address string, app *Application) {
116116
r.HandleFunc("/", middleware.WrapHandler("/", http.HandlerFunc(serveIndex))).Methods("GET")
117117
r.HandleFunc("/queue", middleware.WrapHandler("/queue", http.HandlerFunc(serveIndex))).Methods("GET")
118118
r.HandleFunc("/history", middleware.WrapHandler("/history", http.HandlerFunc(serveIndex))).Methods("GET")
119+
r.HandleFunc("/archive/{id}", middleware.WrapHandler("/archive/{id}", http.HandlerFunc(serveIndex))).Methods("GET")
119120

120121
// Static resources
121122
fileServer := http.FileServer(http.Dir("./dist/assets"))

sitemap.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (app *Application) addVideosToSitemap(sm *stm.Sitemap) error {
7676

7777
// video download url
7878
sm.Add(stm.URL{
79-
"loc": fmt.Sprintf("/api/download/%s/video", video.Id),
79+
"loc": fmt.Sprintf("/archive/%s", video.Id),
8080
"changefreq": "yearly",
8181
"priority": "0.3",
8282
})

src/App.svelte

+3-17
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
<script lang="ts">
22
import "carbon-components-svelte/css/g100.css";
3-
import VideoInput from "./lib/VideoInput.svelte";
4-
import Logo from "./lib/Logo.svelte";
5-
import Heading from "./lib/Heading.svelte";
63
import Notifications from "./lib/Notifications.svelte";
74
import Nav from "./lib/Nav.svelte";
8-
import { Column, Content, Grid, Row } from "carbon-components-svelte";
5+
import { Content, Grid } from "carbon-components-svelte";
96
import { fade } from "svelte/transition";
10-
import VideoEmbed from "./lib/VideoEmbed.svelte";
117
import Queue from "./lib/Queue.svelte";
128
import History from "./lib/History.svelte";
139
import { currentPage, Page } from "./lib/app";
14-
import Stats from "./lib/Stats.svelte";
10+
import Video from "./lib/Video.svelte";
1511
</script>
1612

1713
<Notifications />
@@ -21,17 +17,7 @@
2117
<Grid>
2218
<div transition:fade>
2319
{#if $currentPage === Page.Video}
24-
<Row>
25-
<Column>
26-
<Heading />
27-
<Logo />
28-
<Stats />
29-
</Column>
30-
<Column>
31-
<VideoEmbed />
32-
<VideoInput />
33-
</Column>
34-
</Row>
20+
<Video />
3521
{:else if $currentPage === Page.Queue}
3622
<Queue />
3723
{:else if $currentPage === Page.History}

src/lib/History.svelte

+33-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import SkeletonVideoEntry from "./SkeletonVideoEntry.svelte";
1313
import type { HistoryResponse, VideoInfo } from "./video";
1414
import VideoEntry from "./VideoEntry.svelte";
15-
import { onDestroy } from "svelte";
15+
import { onDestroy, onMount } from "svelte";
1616
import type { SearchMetadata } from "./search";
1717
import { delay } from "./api.js";
1818
import { MeiliSearch, SearchResponse } from "meilisearch";
@@ -21,6 +21,9 @@
2121
let page = 1;
2222
let limit = 25;
2323
24+
$: title = "History - pomu.app";
25+
let onlyOneForArchivePage = false;
26+
2427
let searchValue = "";
2528
let lastSearch: SearchResponse<Partial<VideoInfo>> = null;
2629
$: offset = (page - 1) * limit;
@@ -73,11 +76,15 @@
7376
sort: ["scheduledStart:desc"],
7477
page: page,
7578
offset: offset,
76-
hitsPerPage: limit,
79+
hitsPerPage: onlyOneForArchivePage ? 1 : limit,
7780
}, {
7881
signal: abortController.signal
7982
});
8083
84+
if (onlyOneForArchivePage) {
85+
onlyOneForArchivePage = false;
86+
}
87+
8188
// fix up download urls (as they are not populated, hence the `Partial` in `Partial<VideoInfo>`
8289
search.hits.forEach((part, index, array) => {
8390
array[index].downloadUrl = `/api/download/${part.id}/video`;
@@ -95,9 +102,33 @@
95102
96103
onDestroy(() => abortController.abort());
97104
105+
if (window.location.pathname.startsWith("/archive/")) {
106+
searchValue = window.location.pathname.substring("/archive/".length);
107+
108+
onMount(async () => {
109+
let data = await requestMeilisearchData();
110+
111+
if (!data.enabled) {
112+
return;
113+
}
114+
115+
onlyOneForArchivePage = true;
116+
let search = await startSearch();
117+
118+
if ((search.estimatedTotalHits ?? search.totalHits) >= 1) {
119+
let hit = search.hits[0];
120+
title = `${hit.title} by ${hit.channelName} - archived on pomu.app`;
121+
}
122+
});
123+
}
124+
98125
let history = requestHistory();
99126
</script>
100127

128+
<svelte:head>
129+
<title>{title}</title>
130+
</svelte:head>
131+
101132
<Grid>
102133
<Row>
103134
<Column>

src/lib/Nav.svelte

+7-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@
2424
history.pushState({currentPage: value}, "", `${window.location.origin}/queue`);
2525
break;
2626
case Page.History:
27-
history.pushState({currentPage: value}, "", `${window.location.origin}/history`);
27+
if (window.location.pathname.startsWith("/archive/")) {
28+
const videoId = window.location.pathname.split("/")[2];
29+
history.pushState({currentPage: value}, "", `${window.location.origin}/archive/${videoId}`);
30+
} else {
31+
history.pushState({currentPage: value}, "", `${window.location.origin}/history`);
32+
}
33+
2834
break;
2935
default:
3036
// TODO: Display 404

src/lib/Queue.svelte

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
let queue = requestQueue();
3939
</script>
4040

41+
<svelte:head>
42+
<title>Queue - pomu.app</title>
43+
</svelte:head>
44+
4145
<Row>
4246
<h1>
4347
Queue

src/lib/Video.svelte

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script lang="ts">
2+
import VideoEmbed from "./VideoEmbed.svelte";
3+
import Logo from "./Logo.svelte";
4+
import VideoInput from "./VideoInput.svelte";
5+
import Stats from "./Stats.svelte";
6+
import Heading from "./Heading.svelte";
7+
import { Column, Row } from "carbon-components-svelte";
8+
</script>
9+
10+
<svelte:head>
11+
<title>pomu.app</title>
12+
</svelte:head>
13+
14+
<Row>
15+
<Column>
16+
<Heading />
17+
<Logo />
18+
<Stats />
19+
</Column>
20+
<Column>
21+
<VideoEmbed />
22+
<VideoInput />
23+
</Column>
24+
</Row>

src/lib/VideoEntry.svelte

+30-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import {
33
Button,
4-
Column,
4+
Column, CopyButton,
55
ImageLoader,
66
InlineNotification,
77
Link,
@@ -28,6 +28,7 @@
2828
import VideoLog from "./VideoLog.svelte";
2929
import type { User } from "./api";
3030
import { SearchMetadata } from "./search";
31+
import { showNotification } from "./notifications";
3132
3233
export let info: VideoInfo;
3334
@@ -101,6 +102,17 @@
101102
return results;
102103
}
103104
105+
function copyArchiveToClipboard() {
106+
navigator.clipboard.writeText(`${window.location.origin}/archive/${info.id}`);
107+
108+
showNotification({
109+
title: "Copied permalink to clipboard",
110+
description: "",
111+
timeout: 5000,
112+
kind: "success"
113+
});
114+
}
115+
104116
let submittersModal = false;
105117
</script>
106118

@@ -115,6 +127,11 @@
115127
<Link href="https://youtu.be/{info.id}" target="_blank">
116128
<h4>{info.title}</h4>
117129
</Link>
130+
131+
<copy-container>
132+
<h4 on:click={copyArchiveToClipboard}>#</h4>
133+
</copy-container>
134+
118135
<br />
119136
<h5>
120137
<OutboundLink
@@ -235,4 +252,16 @@
235252
buttons {
236253
display: block;
237254
}
255+
256+
copy-container {
257+
color: gray;
258+
cursor: pointer;
259+
user-select: none;
260+
display: inline-flex;
261+
align-items: center;
262+
}
263+
264+
copy-container:hover {
265+
color: white;
266+
}
238267
</style>

src/lib/app.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ switch (window.location.pathname) {
1616
currentOpenedPage = Page.History;
1717
break;
1818
default:
19-
currentOpenedPage = Page.Video;
19+
if (window.location.pathname.startsWith("/archive/")) {
20+
currentOpenedPage = Page.History;
21+
} else {
22+
currentOpenedPage = Page.Video;
23+
}
24+
2025
break;
2126
}
2227

0 commit comments

Comments
 (0)