diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index b45a645..38298bd 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -3,7 +3,7 @@
{
"name": "Ganymede Frontend",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
- "image": "mcr.microsoft.com/devcontainers/javascript-node:0-20",
+ "image": "mcr.microsoft.com/devcontainers/typescript-node:20",
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
@@ -16,7 +16,9 @@
"customizations": {
"vscode": {
"extensions": [
- "eamodio.gitlens"
+ "eamodio.gitlens",
+ "vunguyentuan.vscode-postcss",
+ "vunguyentuan.vscode-css-variables"
]
}
}
diff --git a/.dockerignore b/.dockerignore
index d862f96..22b7245 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -3,4 +3,6 @@ Dockerfile
node_modules
npm-debug.log
README.md
-.next
\ No newline at end of file
+.next
+!.next/static
+!.next/standalone
diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
index c55c158..44e7ed3 100644
--- a/.github/workflows/docker-publish.yml
+++ b/.github/workflows/docker-publish.yml
@@ -22,55 +22,44 @@ env:
jobs:
build:
runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
- # This is used to complete the identity challenge
- # with sigstore/fulcio when running outside of PRs.
- id-token: write
-
steps:
- name: Checkout repository
- uses: actions/checkout@v3.3.0
+ uses: actions/checkout@v4
+ # Set up QEMU for Arm64
- name: Set up QEMU
- uses: docker/setup-qemu-action@v2.1.0
- with:
- platforms: all
+ uses: docker/setup-qemu-action@v3
- # Workaround: https://github.com/docker/build-push-action/issues/461
- - name: Setup Docker buildx
- uses: docker/setup-buildx-action@v2.2.1
+ # Set up Docker Buildx
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
- # Login against a Docker registry except on PR
- # https://github.com/docker/login-action
+ # Login into GitHub Container Registry except on PR
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
- uses: docker/login-action@v2.1.0
+ uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Extract metadata (tags, labels) for Docker
- # https://github.com/docker/metadata-action
- - name: Extract Docker metadata
+ - name: Extract Docker metadata (release)
id: meta
- uses: docker/metadata-action@v4.3.0
+ uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ flavor: |
+ latest=auto
+ tags: |
+ type=semver,pattern={{version}}
+ type=raw,value=dev
- # Build and push Docker image with Buildx (don't push on PR)
- # https://github.com/docker/build-push-action
- - name: Build and push Docker image
- id: build-and-push
- uses: docker/build-push-action@v3.3.0
+ - name: Build and push
+ uses: docker/build-push-action@v6
with:
- context: .
+ platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
- platforms: linux/amd64,linux/arm64
- provenance: false
- cache-from: type=gha,scope=${{ env.IMAGE_NAME }}
- cache-to: type=gha,scope=${{ env.IMAGE_NAME }},mode=max
+ context: .
+ dockerfile: ./Dockerfile
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e69de29..076b96e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -0,0 +1,9 @@
+{
+ "cssVariables.lookupFiles": [
+ "**/*.css",
+ "**/*.scss",
+ "**/*.sass",
+ "**/*.less",
+ "node_modules/@mantine/core/styles.css"
+ ]
+}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 7271388..cf6d9fe 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,3 +1,5 @@
+ARG GITHUB_SHA
+
# Install dependencies only when needed
FROM node:18-alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
@@ -8,6 +10,9 @@ RUN npm install
# Rebuild the source code only when needed
FROM node:18-alpine AS builder
+
+ENV NEXT_PUBLIC_GIT_COMMIT=$GITHUB_SHA
+
RUN apk add --no-cache git
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
@@ -20,7 +25,6 @@ RUN npm i sharp -y
RUN npm run build
-
# Production image, copy all the files and run next
FROM node:18-alpine AS runner
WORKDIR /app
diff --git a/src/components/Admin/Channels/Delete.tsx b/src/components/Admin/Channels/Delete.tsx
index f4c7e25..21d66e6 100644
--- a/src/components/Admin/Channels/Delete.tsx
+++ b/src/components/Admin/Channels/Delete.tsx
@@ -24,8 +24,8 @@ const AdminChannelsDelete = ({ handleClose, channel }) => {
queryClient.invalidateQueries(["admin-channels"]);
setLoading(false);
showNotification({
- title: "Kanal gelöscht",
- message: "Der Kanal wurde erfolgreich gelöscht.",
+ title: "Channel Deleted",
+ message: "Channel has been deleted successfully",
});
handleClose();
})
@@ -38,7 +38,7 @@ const AdminChannelsDelete = ({ handleClose, channel }) => {
return (
- Bist du sicher, dass du diesen Channel löschen möchtest?
+ Are you sure you want to delete the following channel?
Channel ID: {channel.id}
@@ -48,7 +48,7 @@ const AdminChannelsDelete = ({ handleClose, channel }) => {
- Diese Aktion entfernt keine Dateien
+ This action does not delete any files.
@@ -57,7 +57,7 @@ const AdminChannelsDelete = ({ handleClose, channel }) => {
color="red"
loading={loading}
>
- Löschen
+ Delete
diff --git a/src/components/Admin/Channels/Drawer.tsx b/src/components/Admin/Channels/Drawer.tsx
index 0c704c8..dd99e1c 100644
--- a/src/components/Admin/Channels/Drawer.tsx
+++ b/src/components/Admin/Channels/Drawer.tsx
@@ -55,8 +55,8 @@ const AdminChannelDrawer = ({ handleClose, channel, mode }) => {
queryClient.invalidateQueries(["admin-channels"]);
setLoading(false);
showNotification({
- title: "Kanal aktualisiert",
- message: "Der Kanal wurde erfolgreich aktualisiert.",
+ title: "Channel Updated",
+ message: "Channel has been updated successfully",
});
handleClose();
})
@@ -86,8 +86,8 @@ const AdminChannelDrawer = ({ handleClose, channel, mode }) => {
queryClient.invalidateQueries(["admin-channels"]);
setLoading(false);
showNotification({
- title: "Kanal erstellt",
- message: "Der Kanal wurde erfolgreich erstellt.",
+ title: "Channel Created",
+ message: "Channel has been created successfully",
});
handleClose();
})
@@ -113,8 +113,8 @@ const AdminChannelDrawer = ({ handleClose, channel, mode }) => {
.then(() => {
setUpdateImageLoading(false);
showNotification({
- title: "Kanal Aktualisiert",
- message: "Das Kanalbild wurde Aktualisiert.",
+ title: "Channel Updated",
+ message: "Channel image has been updated successfully",
});
handleClose();
})
diff --git a/src/components/Admin/Channels/Table.tsx b/src/components/Admin/Channels/Table.tsx
index 8412a66..cde279a 100644
--- a/src/components/Admin/Channels/Table.tsx
+++ b/src/components/Admin/Channels/Table.tsx
@@ -122,7 +122,7 @@ const AdminChannelsTable = () => {
title: "Created At",
sortable: true,
render: ({ created_at }) => (
- {dayjs(created_at).format("DD.MM.YYYY")}
+ {dayjs(created_at).format("YYYY/MM/DD")}
),
},
{
diff --git a/src/components/Archive/VodPreview.tsx b/src/components/Archive/VodPreview.tsx
index 9e38f57..2ace9eb 100644
--- a/src/components/Archive/VodPreview.tsx
+++ b/src/components/Archive/VodPreview.tsx
@@ -15,11 +15,11 @@ export const VodPreview = ({ video }: { video: PlatformVideoInfo }) => {
- Veröffentlichungsdatum:
+ Created At:
{video.created_at}
- Dauer:
+ Duration:
{video.duration}
@@ -28,7 +28,7 @@ export const VodPreview = ({ video }: { video: PlatformVideoInfo }) => {
{video.chapters && (
- Kapitel:
+ Chapters:
{video.chapters.length}
)}
diff --git a/src/components/Authentication/Login.tsx b/src/components/Authentication/Login.tsx
index 9198c34..d7c3517 100644
--- a/src/components/Authentication/Login.tsx
+++ b/src/components/Authentication/Login.tsx
@@ -47,7 +47,7 @@ export function LoginForm(props: PaperProps) {
return (
- Willkommen bei Vodarchiv, bitte melde dich an
+ Welcome to Ganymede, login below
{publicRuntimeConfig.SHOW_SSO_LOGIN_BUTTON != "false" && (
@@ -95,7 +95,7 @@ export function LoginForm(props: PaperProps) {
- Du hast noch keinen Account? Dann Registriere dich
+ Don't have an account? Register
diff --git a/src/components/Video/PlaylistModalContent.tsx b/src/components/Video/PlaylistModalContent.tsx
index c6db903..b5dc898 100644
--- a/src/components/Video/PlaylistModalContent.tsx
+++ b/src/components/Video/PlaylistModalContent.tsx
@@ -81,7 +81,7 @@ export const VodPlaylistModalContent = ({ vod }: any) => {
},
});
- if (error) return Fehler beim Laden
;
+ if (error) return failed to load
;
if (isLoading)
return (
diff --git a/src/pages/channels/[channelName].tsx b/src/pages/channels/[channelName].tsx
index 39bd461..9f8ceba 100644
--- a/src/pages/channels/[channelName].tsx
+++ b/src/pages/channels/[channelName].tsx
@@ -55,7 +55,7 @@ const ChannelPage = (props: any) => {
{ value: "clip", label: "Clip" },
];
- useDocumentTitle(`${props.channel.display_name} - VodArchiv`);
+ useDocumentTitle(`${props.channel.display_name} - Ganymede`);
const queryClient = useQueryClient();
diff --git a/src/pages/channels/index.tsx b/src/pages/channels/index.tsx
index e3a3144..d0482b1 100644
--- a/src/pages/channels/index.tsx
+++ b/src/pages/channels/index.tsx
@@ -10,7 +10,7 @@ import { useDocumentTitle } from "@mantine/hooks";
const ChannelsPage = () => {
const queryClient = useQueryClient();
- useDocumentTitle("Kanäle - VODArchiv");
+ useDocumentTitle("Channels - Ganymede");
// React Query
const { isLoading, error, data } = useQuery({
@@ -21,7 +21,7 @@ const ChannelsPage = () => {
),
});
- if (error) return
Fehler beim Laden
;
+ if (error) return
failed to load
;
if (isLoading) return
;
return (
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index d6b6591..f1313fd 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -13,7 +13,7 @@ import { LandingLoggedInHero } from "../components/Landing/LoggedInHero";
export default function Home() {
- useDocumentTitle("VODArchiv");
+ useDocumentTitle("Ganymede");
const user = useUserStore((state) => state);
@@ -23,7 +23,7 @@ export default function Home() {
{user.isLoggedIn && (
- Weiterschauen
+ Continue Watching
@@ -31,7 +31,7 @@ export default function Home() {
)}
- Zuletzt Archiviert
+ Recently Archived
diff --git a/src/pages/login.tsx b/src/pages/login.tsx
index af72d4c..ee92718 100644
--- a/src/pages/login.tsx
+++ b/src/pages/login.tsx
@@ -3,7 +3,7 @@ import { Container } from "@mantine/core";
import { useDocumentTitle } from "@mantine/hooks";
const LoginPage = () => {
- useDocumentTitle("VODArchiv - Login");
+ useDocumentTitle("Ganymede - Login");
return (
diff --git a/src/pages/playlists/[playlistId].tsx b/src/pages/playlists/[playlistId].tsx
index 1b4f363..e50dfb7 100644
--- a/src/pages/playlists/[playlistId].tsx
+++ b/src/pages/playlists/[playlistId].tsx
@@ -16,7 +16,7 @@ const PlaylistPage = (props: any) => {
const [deletePlaylistModalOpened, setDeletePlaylistModalOpened] =
useState(false);
- useDocumentTitle(`VODArchiv - Playlist ${props.playlistId}`);
+ useDocumentTitle(`Ganymede - Playlist ${props.playlistId}`);
const { isLoading, error, data } = useQuery({
queryKey: ["playlist", props.playlistId],
@@ -63,7 +63,7 @@ const PlaylistPage = (props: any) => {
return (
-
{data.name} - VODArchiv Playlist
+
{data.name} - Ganymede Playlist
{
const [showMoreUIDetails, setShowMoreUIDetails] = useState(false);
- useDocumentTitle("Profile - VODArchiv");
+ useDocumentTitle("Profile - Ganymede");
useEffect(() => {
setUseNewChatPlayer(user.settings.useNewChatPlayer);
diff --git a/src/pages/queue/index.tsx b/src/pages/queue/index.tsx
index 631bb67..61ade4f 100644
--- a/src/pages/queue/index.tsx
+++ b/src/pages/queue/index.tsx
@@ -5,7 +5,7 @@ import { Authorization, ROLES } from "../../components/ProtectedRoute";
import QueueTable from "../../components/Queue/Table";
const QueuePage = () => {
- useDocumentTitle("Queue - VODArchiv");
+ useDocumentTitle("Queue - Ganymede");
return (
diff --git a/src/pages/register.tsx b/src/pages/register.tsx
index dddc7a8..380f878 100644
--- a/src/pages/register.tsx
+++ b/src/pages/register.tsx
@@ -4,7 +4,7 @@ import { RegisterForm } from "../components/Authentication/Register";
import { useDocumentTitle } from "@mantine/hooks";
const RegisterPage = () => {
- useDocumentTitle("VODArchiv - Register");
+ useDocumentTitle("Ganymede - Register");
return (
diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx
index fea4350..5a9bff8 100644
--- a/src/pages/search/index.tsx
+++ b/src/pages/search/index.tsx
@@ -30,7 +30,7 @@ const SearchPage = (props: SearchPageProps) => {
const [limit, setLimit] = useState(24);
const handlers = useRef();
- useDocumentTitle("VODArchiv - Suche");
+ useDocumentTitle("Ganymede - Search");
useEffect(() => {
if (props.q && props.q.length > 0) {
diff --git a/src/pages/vods/[vodId].tsx b/src/pages/vods/[vodId].tsx
index 9162179..b1f3571 100644
--- a/src/pages/vods/[vodId].tsx
+++ b/src/pages/vods/[vodId].tsx
@@ -48,7 +48,7 @@ const VodPage = (props: any) => {
const isMobile = useMediaQuery(`(max-width: 1000px)`);
- useDocumentTitle(`VODArchiv - VOD ${props.vodId}`);
+ useDocumentTitle(`Ganymede - VOD ${props.vodId}`);
const { data } = useQuery({
queryKey: ["vod", props.vodId],
@@ -89,7 +89,7 @@ const VodPage = (props: any) => {
return (
-
{data.title} - VODARchiv
+ {data.title} - Ganymede
{checkLoginRequired() && }
{!checkLoginRequired() && (