diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json
index 6c5aa32c..f59f1e87 100644
--- a/src/locales/en/translation.json
+++ b/src/locales/en/translation.json
@@ -7,7 +7,6 @@
"no_results": "No results found"
},
"sidebar": {
- "home": "Home",
"catalogue": "Catalogue",
"downloads": "Downloads",
"settings": "Settings",
@@ -16,7 +15,9 @@
"checking_files": "{{title}} ({{percentage}} - Checking files…)",
"paused": "{{title}} (Paused)",
"downloading": "{{title}} ({{percentage}} - Downloading…)",
- "filter": "Filter library"
+ "filter": "Filter library",
+ "follow_us": "Follow us",
+ "home": "Home"
},
"header": {
"search": "Search",
diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json
index 4cc90d15..9ac401bf 100644
--- a/src/locales/es/translation.json
+++ b/src/locales/es/translation.json
@@ -16,7 +16,8 @@
"paused": "{{title}} (Pausado)",
"downloading": "{{title}} ({{percentage}} - Descargando…)",
"filter": "Filtrar biblioteca",
- "home": "Hogar"
+ "home": "Hogar",
+ "follow_us": "Síganos"
},
"header": {
"search": "Buscar",
diff --git a/src/locales/fr/translation.json b/src/locales/fr/translation.json
index f4250be2..c83a825b 100644
--- a/src/locales/fr/translation.json
+++ b/src/locales/fr/translation.json
@@ -16,7 +16,8 @@
"paused": "{{title}} (En pause)",
"downloading": "{{title}} ({{percentage}} - Téléchargement en cours…)",
"filter": "Filtrer la bibliothèque",
- "home": "Maison"
+ "home": "Maison",
+ "follow_us": "Suivez-nous"
},
"header": {
"search": "Recherche",
diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json
index a19ca24a..145163b4 100644
--- a/src/locales/pt/translation.json
+++ b/src/locales/pt/translation.json
@@ -16,7 +16,8 @@
"paused": "{{title}} (Pausado)",
"downloading": "{{title}} ({{percentage}} - Baixando…)",
"filter": "Filtrar biblioteca",
- "home": "Início"
+ "home": "Início",
+ "follow_us": "Acompanhe-nos"
},
"header": {
"search": "Buscar",
diff --git a/src/main/events/index.ts b/src/main/events/index.ts
index 866f8317..5eaceff5 100644
--- a/src/main/events/index.ts
+++ b/src/main/events/index.ts
@@ -1,30 +1,31 @@
-import { app, ipcMain } from "electron";
import { defaultDownloadsPath } from "@main/constants";
+import { app, ipcMain } from "electron";
-import "./library/add-game-to-library";
-import "./catalogue/search-games";
-import "./catalogue/get-game-shop-details";
import "./catalogue/get-catalogue";
-import "./library/get-library";
+import "./catalogue/get-game-shop-details";
+import "./catalogue/get-games";
+import "./catalogue/get-how-long-to-beat";
+import "./catalogue/get-random-game";
+import "./catalogue/search-games";
import "./hardware/get-disk-free-space";
+import "./library/add-game-to-library";
+import "./library/close-game";
+import "./library/delete-game-folder";
+import "./library/get-game-by-object-id";
+import "./library/get-library";
+import "./library/get-repackers-friendly-names";
+import "./library/open-game";
+import "./library/open-game-installer";
+import "./library/remove-game";
+import "./misc/get-or-cache-image";
+import "./misc/open-external";
+import "./misc/show-open-dialog";
import "./torrenting/cancel-game-download";
import "./torrenting/pause-game-download";
import "./torrenting/resume-game-download";
import "./torrenting/start-game-download";
-import "./misc/get-or-cache-image";
-import "./user-preferences/update-user-preferences";
import "./user-preferences/get-user-preferences";
-import "./library/get-repackers-friendly-names";
-import "./library/get-game-by-object-id";
-import "./library/open-game-installer";
-import "./library/open-game";
-import "./library/close-game";
-import "./misc/show-open-dialog";
-import "./library/remove-game";
-import "./library/delete-game-folder";
-import "./catalogue/get-random-game";
-import "./catalogue/get-how-long-to-beat";
-import "./catalogue/get-games";
+import "./user-preferences/update-user-preferences";
ipcMain.handle("ping", () => "pong");
ipcMain.handle("getVersion", () => app.getVersion());
diff --git a/src/main/events/misc/open-external.ts b/src/main/events/misc/open-external.ts
new file mode 100644
index 00000000..3d693c23
--- /dev/null
+++ b/src/main/events/misc/open-external.ts
@@ -0,0 +1,9 @@
+import { shell } from "electron";
+import { registerEvent } from "../register-event";
+
+const openExternal = async (_event: Electron.IpcMainInvokeEvent, src: string) =>
+ shell.openExternal(src);
+
+registerEvent(openExternal, {
+ name: "openExternal",
+});
diff --git a/src/preload.ts b/src/preload.ts
index db765453..93acde24 100644
--- a/src/preload.ts
+++ b/src/preload.ts
@@ -86,6 +86,7 @@ contextBridge.exposeInMainWorld("electron", {
ping: () => ipcRenderer.invoke("ping"),
getVersion: () => ipcRenderer.invoke("getVersion"),
getDefaultDownloadsPath: () => ipcRenderer.invoke("getDefaultDownloadsPath"),
+ openExternal: (src: string) => ipcRenderer.invoke("openExternal", src),
showOpenDialog: (options: Electron.OpenDialogOptions) =>
ipcRenderer.invoke("showOpenDialog", options),
platform: process.platform,
diff --git a/src/renderer/assets/discord-icon.svg b/src/renderer/assets/discord-icon.svg
new file mode 100644
index 00000000..2fba46cd
--- /dev/null
+++ b/src/renderer/assets/discord-icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/assets/x-icon.svg b/src/renderer/assets/x-icon.svg
new file mode 100644
index 00000000..f594427b
--- /dev/null
+++ b/src/renderer/assets/x-icon.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/renderer/components/bottom-panel/bottom-panel.css.ts b/src/renderer/components/bottom-panel/bottom-panel.css.ts
index 632e1bff..f251d1c0 100644
--- a/src/renderer/components/bottom-panel/bottom-panel.css.ts
+++ b/src/renderer/components/bottom-panel/bottom-panel.css.ts
@@ -1,5 +1,5 @@
-import { SPACING_UNIT, vars } from "../../theme.css";
import { style } from "@vanilla-extract/css";
+import { SPACING_UNIT, vars } from "../../theme.css";
export const bottomPanel = style({
width: "100%",
@@ -14,9 +14,10 @@ export const bottomPanel = style({
});
export const downloadsButton = style({
- cursor: "pointer",
color: vars.color.bodyText,
+ borderBottom: "1px solid transparent",
":hover": {
- textDecoration: "underline",
+ borderBottom: `1px solid ${vars.color.bodyText}`,
+ cursor: "pointer",
},
});
diff --git a/src/renderer/components/sidebar/sidebar.css.ts b/src/renderer/components/sidebar/sidebar.css.ts
index 8bf62781..e4ff22f8 100644
--- a/src/renderer/components/sidebar/sidebar.css.ts
+++ b/src/renderer/components/sidebar/sidebar.css.ts
@@ -6,6 +6,7 @@ export const sidebar = recipe({
base: {
backgroundColor: vars.color.darkBackground,
color: "#c0c1c7",
+ flexDirection: "column",
display: "flex",
transition: "opacity ease 0.2s",
borderRight: `solid 1px ${vars.color.borderColor}`,
@@ -134,3 +135,36 @@ export const section = recipe({
},
},
});
+
+export const sidebarFooter = style({
+ marginTop: "auto",
+ padding: `${SPACING_UNIT * 2}px`,
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "space-between",
+});
+
+export const footerSocialsContainer = style({
+ display: "flex",
+ alignItems: "center",
+ gap: `${SPACING_UNIT * 1.5}px`,
+});
+
+export const footerSocialsItem = style({
+ color: vars.color.bodyText,
+ backgroundColor: vars.color.darkBackground,
+ width: "16px",
+ height: "16px",
+ display: "flex",
+ alignItems: "center",
+ transition: "all ease 0.15s",
+ ":hover": {
+ opacity: 0.75,
+ cursor: "pointer",
+ },
+});
+
+export const footerText = style({
+ color: vars.color.bodyText,
+ fontSize: "12px",
+});
diff --git a/src/renderer/components/sidebar/sidebar.tsx b/src/renderer/components/sidebar/sidebar.tsx
index 962ecdfe..ad1bcdf3 100644
--- a/src/renderer/components/sidebar/sidebar.tsx
+++ b/src/renderer/components/sidebar/sidebar.tsx
@@ -4,13 +4,32 @@ import { useLocation, useNavigate } from "react-router-dom";
import type { Game } from "@types";
-import { useDownload, useLibrary } from "@renderer/hooks";
import { AsyncImage, TextField } from "@renderer/components";
+import { useDownload, useLibrary } from "@renderer/hooks";
import { SPACING_UNIT } from "@renderer/theme.css";
-import * as styles from "./sidebar.css";
import { routes } from "./routes";
+import { MarkGithubIcon } from "@primer/octicons-react";
+import DiscordLogo from "@renderer/assets/discord-icon.svg";
+import XLogo from "@renderer/assets/x-icon.svg";
+import * as styles from "./sidebar.css";
+
+const socials = [
+ {
+ url: "https://discord.gg/hydralauncher",
+ icon: ,
+ },
+ {
+ url: "https://twitter.com/hydralauncher",
+ icon: ,
+ },
+ {
+ url: "https://github.com/hydralauncher/hydra",
+ icon: ,
+ },
+];
+
const SIDEBAR_MIN_WIDTH = 200;
const SIDEBAR_INITIAL_WIDTH = 250;
const SIDEBAR_MAX_WIDTH = 450;
@@ -212,6 +231,24 @@ export function Sidebar() {
className={styles.handle}
onMouseDown={handleMouseDown}
/>
+
+
);
}
diff --git a/src/renderer/declaration.d.ts b/src/renderer/declaration.d.ts
index 3db1a7c0..cceed299 100644
--- a/src/renderer/declaration.d.ts
+++ b/src/renderer/declaration.d.ts
@@ -1,12 +1,12 @@
import type {
- CatalogueEntry,
- GameShop,
- Game,
CatalogueCategory,
- TorrentProgress,
- ShopDetails,
- UserPreferences,
+ CatalogueEntry,
+ Game,
+ GameShop,
HowLongToBeatCategory,
+ ShopDetails,
+ TorrentProgress,
+ UserPreferences,
} from "@types";
import type { DiskSpace } from "check-disk-space";
@@ -78,6 +78,7 @@ declare global {
/* Misc */
getOrCacheImage: (url: string) => Promise;
+ openExternal: (src: string) => Promise;
getVersion: () => Promise;
ping: () => string;
getDefaultDownloadsPath: () => Promise;
diff --git a/src/renderer/pages/patch-notes/patch-notes-skeleton.tsx b/src/renderer/pages/patch-notes/patch-notes-skeleton.tsx
new file mode 100644
index 00000000..e69de29b