Skip to content
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

Colorscheme refactoring and fixes #179

Merged
merged 17 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</NuxtLayout>
</template>

<script>
<script lang="ts">
// workaround for bootstrap javascript
export default {
head() {
Expand Down
24 changes: 18 additions & 6 deletions frontend/assets/styles/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
@import url('https://fonts.googleapis.com/css2?family=Barlow:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
:root {
--border-radius: 8px;
}

[data-theme="dark"] {
/* Dark/Light mode variables */
--bg-color: #0f0f0f;
--bg-card-glass: #1d1d1d;
Expand All @@ -26,7 +23,7 @@
--nav-item-hover:#f0f0f0;
}

[data-theme="light"] {
.light {
/* Dark/Light mode variables */
--bg-color: rgb(252, 252, 252);
--bg-card-glass: #f5f5f5;
Expand Down Expand Up @@ -94,12 +91,10 @@ hr {
}

/* Glassmorphism properties */

.glass-card {
backdrop-filter: blur(16px) saturate(200%);
-webkit-backdrop-filter: blur(16px) saturate(200%);
background-color: var(--bg-card-glass);
/* background-color: rgba(var(--bg-color), 0.78); */
border-radius: 12px;
border: 1px solid var(--border-color-cards);
}
Expand All @@ -109,6 +104,23 @@ hr {
opacity: 40%;
}

/* Page Transitions */
.page-enter-active,
.page-leave-active {
transition: all 0.25s;
}

.page-enter-from {
opacity: 0;
filter: blur(0%);
}

.page-leave-from {
opacity: 100%;
filter: blur(100%);
}


/* Responsive properties */
@media (min-width: 1581px) {
#__nuxt {
Expand Down
6 changes: 0 additions & 6 deletions frontend/components/CardAPI.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,6 @@ const getFavicon = (url: string, size: number) => {
return `https://www.google.com/s2/favicons?domain=${url}&sz=${size}`;
};

// const handleFavicon = () => {
// return props.faviconSrc
// ? props.faviconSrc !== null
// : getFavicon(props.faviconSrc, 128);
// };

onMounted(() => {
iconCategory?.();
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/components/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,13 @@

<script setup lang="ts">
import packageJson from "../package.json";
import { computed, inject, Ref } from "vue";

const theme = useState("APIVaultTheme", () =>
process.client ? localStorage.getItem("APIVaultTheme")! : "dark"
);

const logoMode = computed(() => {
if (theme!.value === "dark") {
if (theme!.value === "dark" || theme.value === null) {
return "/img/apivault-dark-nobg.png";
}
return "/img/apivault-light-nobg.png";
Expand Down
43 changes: 24 additions & 19 deletions frontend/components/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<li class="nav-item navbar-text-wrapper mt-2">
<ToggleButton
@click="setModeLocal"
:theme="theme"
class="flex items-center gap-2 ms-2"
/>
</li>
Expand Down Expand Up @@ -137,51 +138,55 @@
import { categoriesProperties } from "../utils/categoryMapping";
import GithubService from "../services/GithubServices";
import {
setThemeElements,
getThemeElements,
themeIcons,
setThemeLogoPath,
setIconThemeText,
setLocalStorage,
} from "../utils/themeutils";

const stargazers = await GithubService.repoStars();
console.log(stargazers);
const categoriesAttributes = categoriesProperties;
const theme = useState("APIVaultTheme", () =>
process.client ? localStorage.getItem("APIVaultTheme")! : "dark"
process.client ? localStorage.getItem("APIVaultTheme")! : "light"
);
const iconTheme = ref(themeIcons[theme.value]);
const iconThemeText = ref(setIconThemeText(theme));
const logoPath = ref(setThemeLogoPath(theme));

/**
Toggles the color scheme of the document body between light and dark mode.
Updates the values of iconThemeText, theme, logoPath, and iconTheme
based on the new color scheme. Returns the new value of iconTheme to display.
@returns {String} - The new value of iconTheme to display
*/
let defaultTheme = ref<boolean>(true);
const setModeLocal = (): void => {
if (process.client) {
setLocalStorage(theme);
defaultTheme.value = setLocalStorage(theme);
defaultTheme.value = getThemeElements(theme);
}
const themeText = setThemeElements(theme);
iconThemeText.value = themeText;
iconTheme.value = themeIcons[theme.value];
logoPath.value = setThemeLogoPath(theme);
};

/**
This is needed to set the dafault theme class for first
visit on the website.
*/
useHead({
htmlAttrs: {
class: computed(() => {
return defaultTheme.value ? "" : "light";
}),
},
});

onMounted(() => {
document
.querySelector("body")
?.setAttribute("data-theme", localStorage.getItem("APIVaultTheme")!);
if (localStorage.getItem("APIVaultTheme") === null) {
localStorage.setItem("APIVaultTheme", "dark");
} else {
theme.value = localStorage.getItem("APIVaultTheme")!;
const themeText = setThemeElements(theme);
iconThemeText.value = themeText;
iconTheme.value = themeIcons[theme.value];
logoPath.value = setThemeLogoPath(theme);
}
theme.value = setTheme();
const isDarkTheme: boolean = theme.value === "dark" || theme.value === null;
defaultTheme.value = isDarkTheme;
iconTheme.value = themeIcons[theme.value];
logoPath.value = setThemeLogoPath(theme);
});
</script>

Expand Down
45 changes: 20 additions & 25 deletions frontend/components/ToggleButton.vue
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
<template>
<button class="toggle-button" :class="{ active: isActive }" @click="toggle">
<span class="toggle-icon">
<font-awesome-icon :icon="icon" />
<font-awesome-icon :icon="['fas', icon]" />
</span>
</button>
</template>

<script lang="ts">
import { ref, computed } from "vue";
export default {
setup() {
const isActive = ref(false);
<script lang="ts" setup>
const isActive = ref(false);

const toggle = () => {
isActive.value = !isActive.value;
};
const toggle = () => {
isActive.value = !isActive.value;
};

const icon = computed(() => {
return isActive.value ? "sun" : "moon";
});
const icon = computed(() => {
return isActive.value ? "sun" : "moon";
});

return {
isActive,
toggle,
icon,
};
},
};
onMounted(() => {
const isLight = localStorage.getItem("APIVaultTheme");
isActive.value = true ? isLight === "light" : false;
});
</script>

<style>
Expand All @@ -50,15 +44,16 @@ export default {
}

.toggle-icon {
display: flex;
position: absolute;
left: 0;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
background-color: #fff;
border-radius: 50%;
color: var(--icon-color);
display: flex;
justify-content: center;
height: 30px;
left: 0;
position: absolute;
transition: transform 0.3s ease;
width: 30px;
}
</style>
30 changes: 15 additions & 15 deletions frontend/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,13 @@ export default defineNuxtConfig({
plugins: [
'@/plugins/fontawesome',
],
modules: ['@nuxtjs/color-mode'],
css: [
'~/assets/styles/bootstrap.scss',
'~/assets/styles/main.css',
'~/assets/styles/normalize.css',
'~/assets/styles/animations.scss',
'@fortawesome/fontawesome-svg-core/styles.css'
],
build: {
transpile: ['@fortawesome/vue-fontawesome']
},
app: {
pageTransition: {
name: "page",
mode: "out-in",
},
head: {
title: "A free API database list for developers",
bodyAttrs: {
'data-theme': 'dark'
},
meta: [
{ name: "keywords", content: "free api, apivault, api list, open-source, public APIs, software developer" },
{ name: "description", content: "ApiVault - The largest collection of free public APIs, categorized for easy search." },
Expand All @@ -49,5 +39,15 @@ export default defineNuxtConfig({
{ property: "og:type", content: "website"}
]
}
}
},
css: [
'~/assets/styles/bootstrap.scss',
'~/assets/styles/main.css',
'~/assets/styles/normalize.css',
'~/assets/styles/animations.scss',
'@fortawesome/fontawesome-svg-core/styles.css'
],
build: {
transpile: ['@fortawesome/vue-fontawesome']
},
})
3 changes: 1 addition & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nuxt-app",
"version": "2.0.0-b1",
"version": "2.0.0-b2.002",
"private": true,
"scripts": {
"build": "nuxt build",
Expand All @@ -24,7 +24,6 @@
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/vue-fontawesome": "^3.0.3",
"@nuxtjs/color-mode": "^3.2.0",
"@popperjs/core": "^2.11.7",
"axios": "^1.3.5",
"bootstrap": "^5.2.3",
Expand Down
35 changes: 9 additions & 26 deletions frontend/utils/themeutils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
export type Theme = "light" | "dark";

export function getTheme(): string {
export function setTheme(): string {
const theme = localStorage.getItem("APIVaultTheme");
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
if (process.client) {
Expand All @@ -20,40 +18,25 @@ export const themeIcons: { [key: string]: string } = {
dark: "fa-solid fa-moon",
};

export const setThemeElements = (theme: globalThis.Ref<string>): string => {
const themeText =
theme.value[0].toUpperCase() +
theme.value.slice(1, theme.value.length) +
" Mode";
if (theme.value === null) {
document.querySelector("body")?.setAttribute("data-theme", "dark");
}
document.querySelector("body")?.setAttribute("data-theme", theme.value);
return themeText;
export const getThemeElements = (theme: globalThis.Ref<string>): boolean => {
return theme.value === null || theme.value === 'dark';
}

export const setThemeLogoPath = (theme: globalThis.Ref<string>): string => {
if (theme.value === null || theme.value === undefined) {
return `/img/apivault-full-dark-nobg.png`;
}
return `/img/apivault-full-${theme.value}-nobg.png`;
}

/**
This code generates a string that represents the mode of the theme,
either "Light Mode" or "Dark Mode", depending on the theme.value
*/
export const setIconThemeText = (theme: globalThis.Ref<string>): string => {
return theme.value
? theme.value[0].toUpperCase() +
theme.value.slice(1, theme.value.length) +
" Mode"
: " Mode"
}

export const setLocalStorage = (theme: globalThis.Ref<string>): void => {
export const setLocalStorage = (theme: globalThis.Ref<string>): boolean => {
if (theme.value === "dark" || theme.value === undefined) {
theme.value = "light";
localStorage.setItem("APIVaultTheme", "light");
return false;
} else {
theme.value = "dark";
localStorage.setItem("APIVaultTheme", "dark");
return true;
}
}