Se connecter
diff --git a/styles/globals.scss b/styles/globals.scss
index a5cacf3..7827b51 100644
--- a/styles/globals.scss
+++ b/styles/globals.scss
@@ -83,7 +83,7 @@ li {
}
}
-button {
+button:not(.reset) {
cursor: pointer;
width: 100%;
color: #fff;
@@ -172,6 +172,14 @@ select:not(.nostyle) {
}
}
+.reset {
+ background-color: inherit;
+ color: inherit;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
@media (max-width: 1280px) {
.App {
width: 100%;
diff --git a/styles/home/categories.module.scss b/styles/home/categories.module.scss
deleted file mode 100644
index 765776b..0000000
--- a/styles/home/categories.module.scss
+++ /dev/null
@@ -1,225 +0,0 @@
-.categories-wrapper {
- height: 100%;
- width: 300px;
- padding: 0 25px 0 10px;
- border-right: 1px solid #dadce0;
- margin-right: 15px;
- display: flex;
- align-items: center;
- flex-direction: column;
- overflow: hidden;
-
- & .block-wrapper {
- height: auto;
- width: 100%;
-
- & h4 {
- user-select: none;
- text-transform: uppercase;
- font-size: 0.85em;
- color: #bbb;
- margin-bottom: 5px;
- }
-
- // List items
- & .items {
- animation: fadein 0.3s both;
- }
- & .items .item {
- position: relative;
- user-select: none;
- cursor: pointer;
- height: fit-content;
- width: 100%;
- background-color: #fff;
- padding: 7px 12px;
- border: 1px solid #dadce0;
- border-bottom: 2px solid #dadce0;
- border-radius: 3px;
- transition: 0.15s;
-
- &:not(:last-child) {
- margin-bottom: 5px;
- }
-
- &.active {
- color: #fff;
- background: #3f88c5;
- border-color: #3f88c5;
- }
-
- &:hover:not(.active) {
- color: #3f88c5;
- background: #f0eef6;
- border-bottom: 2px solid #3f88c5;
- }
- }
- }
-
- // Favorites
- & .block-wrapper.favorites {
- margin-bottom: 15px;
-
- & .items .item {
- padding: 0;
- display: flex;
- align-items: center;
- }
-
- & .items .no-fav-link {
- user-select: none;
- text-align: center;
- font-style: italic;
- font-size: 0.9em;
- color: #bbb;
- }
-
- & .items .item a {
- width: 100%;
- text-decoration: none;
- color: inherit;
- padding: 7px 12px;
- border: 0 !important;
- }
-
- & .items .item .category {
- color: #bbb;
- font-size: 0.85em;
- }
- }
-
- // Categories
- & .block-wrapper.categories {
- min-height: 0;
- display: flex;
- flex: 1;
- flex-direction: column;
-
- & .items {
- padding-right: 5px;
- overflow-y: scroll;
-
- & .item {
- display: flex;
- align-items: center;
- justify-content: space-between;
-
- &.active .menu-item .option-edit svg {
- fill: #fff;
- }
-
- & .content {
- width: 100%;
- display: flex;
- flex: 1;
- align-items: center;
-
- & .name {
- margin-right: 5px;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- }
-
- & .links-count {
- min-width: fit-content;
- font-size: 0.85em;
- color: #bbb;
- }
- }
- &:hover .content {
- width: calc(100% - 42px);
- }
-
- & .menu-item {
- height: 100%;
- min-width: fit-content;
- margin-left: 5px;
- display: none;
- gap: 2px;
- align-items: center;
- justify-content: center;
- animation: fadein 0.3s both;
-
- & > a {
- border: 0;
- margin: 0;
- padding: 0;
- display: flex;
- align-items: center;
- justify-content: center;
-
- &:hover {
- transform: scale(1.25);
- }
-
- & svg {
- height: 20px;
- width: 20px;
- }
- }
- }
- &:hover .menu-item {
- display: flex;
- }
- }
- }
- }
-
- // Controls
- .controls {
- margin: 10px 0;
- display: flex;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- }
-
- // User Card
- & .user-card-wrapper {
- position: relative;
- user-select: none;
- height: fit-content;
- width: 100%;
- color: #333;
- background-color: #fff;
-
- & .user-card {
- border: 1px solid #dadce0;
- padding: 7px 12px;
- display: flex;
- gap: 10px;
- align-items: center;
-
- & img {
- border-radius: 50%;
- }
- }
-
- & .disconnect-btn {
- position: absolute;
- top: 0;
- left: 0;
- height: 100%;
- width: 100%;
- color: #fff;
- display: none;
- }
-
- &:hover .disconnect-btn {
- display: block;
- }
- }
-}
-
-@keyframes fadein {
- 0% {
- transform: translateX(-15px);
- opacity: 0;
- }
-
- 100% {
- transform: translateX(0);
- opacity: 1;
- }
-}
diff --git a/styles/home/links.module.scss b/styles/home/links.module.scss
deleted file mode 100644
index 2097b14..0000000
--- a/styles/home/links.module.scss
+++ /dev/null
@@ -1,139 +0,0 @@
-.no-link,
-.no-category {
- display: flex;
- flex: 1;
- align-items: center;
- justify-content: center;
- flex-direction: column;
- animation: fadein 0.3s both;
-}
-
-.links-wrapper {
- height: 100%;
- padding: 10px;
- display: flex;
- flex: 1;
- flex-direction: column;
- overflow-x: hidden;
- overflow-y: scroll;
-
- & h2 {
- color: #3f88c5;
- margin-bottom: 15px;
-
- & .links-count {
- color: #bbb;
- font-weight: 300;
- font-size: 0.8em;
- }
- }
-
- & .links {
- width: 100%;
- display: flex;
- flex: 1;
- flex-direction: column;
- animation: fadein 0.3s both; // bug on drag start
- }
-
- & .links .link {
- user-select: none;
- cursor: pointer;
- height: fit-content;
- width: 100%;
- color: #3f88c5;
- background-color: #fff;
- padding: 10px 15px;
- border: 1px solid #dadce0;
- border-bottom: 2px solid #dadce0;
- border-radius: 3px;
- margin-bottom: 10px;
- display: flex;
- align-items: center;
- transition: 0.15s;
-
- &:hover {
- border-bottom-color: #3f88c5;
- background: #f0eef6;
-
- & .url-pathname {
- animation: fadein 0.3s both;
- }
-
- & .controls {
- display: flex;
- animation: fadein 0.3s both;
- }
- }
-
- & > a {
- height: 100%;
- max-width: calc(100% - 50px);
- text-decoration: none;
- display: flex;
- flex: 1;
- flex-direction: column;
- transition: 0.1s;
-
- &,
- &:hover {
- border: 0;
- }
-
- & .link-name .link-category {
- color: #bbb;
- font-size: 0.9em;
- }
-
- & .link-url {
- width: 100%;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- color: #bbb;
- font-size: 0.8em;
-
- & .url-pathname {
- opacity: 0;
- }
- }
- }
-
- & .controls {
- display: none;
- align-items: center;
- justify-content: center;
- gap: 10px;
-
- & > a {
- border: 0;
- margin: 0;
- padding: 0;
- display: flex;
- align-items: center;
- justify-content: center;
-
- &:hover {
- transform: scale(1.3);
- }
-
- & svg {
- height: 20px;
- width: 20px;
- }
- }
- }
- }
-}
-
-@keyframes fadein {
- 0% {
- transform: translateX(-15px);
- opacity: 0;
- }
-
- 100% {
- transform: translateX(0);
- opacity: 1;
- }
-}
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..de144e3
--- /dev/null
+++ b/test.js
@@ -0,0 +1,60 @@
+(async () => {
+ const request = await fetch("https://sdtream.sonnydata.fr");
+ const text = await request.text();
+
+ const faviconPath = findFaviconPath(text);
+ if (!faviconPath) {
+ return console.log("Unable to find favicon path");
+ }
+
+ if (isBase64Image(faviconPath)) {
+ console.log("base64, convert it to buffer");
+ const buffer = convertBase64ToBuffer(faviconPath);
+ return console.log(buffer);
+ }
+
+ const pathWithoutFile = popLastSegment(request.url);
+ console.log("pathWithoutFile", pathWithoutFile);
+
+ const result = buildFaviconUrl(faviconPath, pathWithoutFile);
+ console.log(result);
+})();
+
+function findFaviconPath(text) {
+ const regex = /rel=['"](?:shortcut )?icon['"] href=['"]([^?'"]+)[?'"]/i;
+ const found = text.match(regex);
+ if (!found) {
+ return console.warn("nothing, exit");
+ }
+
+ const faviconPath = found?.[1];
+ return faviconPath || null;
+}
+
+function popLastSegment(url = "") {
+ const { href } = new URL(url);
+ const pathWithoutFile = href.split("/");
+ pathWithoutFile.pop();
+ return pathWithoutFile.join("/") || "";
+}
+
+function buildFaviconUrl(faviconPath, pathWithoutFile) {
+ if (faviconPath.startsWith("http")) {
+ console.log("startsWith http, result", faviconPath);
+ return faviconPath;
+ } else if (faviconPath.startsWith("/")) {
+ console.log("startsWith /, result", pathWithoutFile + faviconPath);
+ return pathWithoutFile + faviconPath;
+ } else {
+ console.log("else, result", pathWithoutFile + "/" + faviconPath);
+ return pathWithoutFile + "/" + faviconPath;
+ }
+}
+
+function isBase64Image(data) {
+ return data.startsWith("data:image/");
+}
+
+function convertBase64ToBuffer(base64 = "") {
+ return new Buffer.from(base64, "base64");
+}
diff --git a/tsconfig.json b/tsconfig.json
index d89876a..b8d5978 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,31 +1,20 @@
{
- "compilerOptions": {
- "target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "strict": false,
- "forceConsistentCasingInFileNames": true,
- "noEmit": true,
- "esModuleInterop": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "jsx": "preserve",
- "incremental": true
- },
- "include": [
- "next-env.d.ts",
- "**/*.ts",
- "**/*.tsx"
- ],
- "exclude": [
- "node_modules"
- ]
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
}
-
\ No newline at end of file
diff --git a/utils/client.ts b/utils/client.ts
new file mode 100644
index 0000000..568b75f
--- /dev/null
+++ b/utils/client.ts
@@ -0,0 +1,7 @@
+import { NextRouter } from 'next/router';
+
+export function redirectWithoutClientCache(router: NextRouter, url: string) {
+ router.push(url, undefined, {
+ unstable_skipClientCache: true,
+ });
+}
\ No newline at end of file
diff --git a/utils/link.ts b/utils/link.ts
new file mode 100644
index 0000000..edb32f5
--- /dev/null
+++ b/utils/link.ts
@@ -0,0 +1,3 @@
+export function faviconLinkBuilder(origin: string, size: number = 32) {
+ return `http://localhost:3000/api/favicon?url=${origin}`;
+}