Skip to content
This repository has been archived by the owner on Dec 12, 2024. It is now read-only.

🔨[refactor] [Configure Vanilla.js app to be a PWA.] #383

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
9 changes: 9 additions & 0 deletions javascript/dwa-starter-vanillajs-vite/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DWA Starter</title>
<meta
name="description"
content="A Decentralized Web Application template"
/>
<link rel="stylesheet" href="style.css" />
<link rel="icon" href="/favicon.ico" sizes="48x48" />
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon-180x180.png" />
<link rel="manifest" href="/manifest.json" />
</head>
<body>
<nav>
Expand All @@ -14,6 +22,7 @@
<li><a href="/settings" data-link>Settings</a></li>
</ul>
</nav>
<button id="install-button" style="display: none">Install App</button>
<div id="app"></div>
<script type="module" src="/main.js"></script>
</body>
Expand Down
138 changes: 70 additions & 68 deletions javascript/dwa-starter-vanillajs-vite/main.js
Original file line number Diff line number Diff line change
@@ -1,101 +1,103 @@
// main.js

import { Home, About, Settings, NotFound } from "./components.js";
// Function to create and render the toggle button
function createThemeToggleButton() {
console.log('Creating theme toggle button');
const nav = document.querySelector('nav');
const button = document.createElement('button');
button.id = 'theme-toggle';
button.textContent = 'Toggle Theme';
button.setAttribute('aria-label', 'Toggle Dark Mode');
button.classList.add('theme-toggle-btn');
nav.appendChild(button);
button.addEventListener('click', toggleTheme);
console.log('Theme toggle button created and added to nav');
console.log("Creating theme toggle button");
const nav = document.querySelector("nav");
const button = document.createElement("button");
button.id = "theme-toggle";
button.textContent = "Toggle Theme";
button.setAttribute("aria-label", "Toggle Dark Mode");
button.classList.add("theme-toggle-btn");
nav.appendChild(button);
button.addEventListener("click", toggleTheme);
console.log("Theme toggle button created and added to nav");
}

function toggleTheme() {
console.log('Toggle theme function called');
const body = document.body;
const isDarkMode = body.classList.contains('dark-mode');
console.log('Current mode is dark:', isDarkMode);

if (isDarkMode) {
body.classList.remove('dark-mode');
body.classList.add('light-mode');
console.log('Switched to light mode:', body.classList); // Log class list
} else {
body.classList.remove('light-mode');
body.classList.add('dark-mode');
console.log('Switched to dark mode:', body.classList); // Log class list
}
localStorage.setItem('theme', isDarkMode ? 'light' : 'dark');
}
console.log("Toggle theme function called");
const body = document.body;
const isDarkMode = body.classList.contains("dark-mode");
console.log("Current mode is dark:", isDarkMode);

if (isDarkMode) {
body.classList.remove("dark-mode");
body.classList.add("light-mode");
console.log("Switched to light mode:", body.classList); // Log class list
} else {
body.classList.remove("light-mode");
body.classList.add("dark-mode");
console.log("Switched to dark mode:", body.classList); // Log class list
}
localStorage.setItem("theme", isDarkMode ? "light" : "dark");
}

// Apply stored theme preference or system preference on load
function applyStoredTheme() {
console.log('Applying stored theme');
const storedTheme = localStorage.getItem('theme');
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
const body = document.body;
console.log("Applying stored theme");
const storedTheme = localStorage.getItem("theme");
const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
const body = document.body;

console.log('Stored theme:', storedTheme);
console.log('System prefers dark scheme:', prefersDarkScheme.matches);
console.log("Stored theme:", storedTheme);
console.log("System prefers dark scheme:", prefersDarkScheme.matches);

if (storedTheme === 'dark' || (storedTheme === null && prefersDarkScheme.matches)) {
body.classList.add('dark-mode');
console.log('Applied dark mode');
} else {
body.classList.add('light-mode');
console.log('Applied light mode');
}
if (
storedTheme === "dark" ||
(storedTheme === null && prefersDarkScheme.matches)
) {
body.classList.add("dark-mode");
console.log("Applied dark mode");
} else {
body.classList.add("light-mode");
console.log("Applied light mode");
}
}

// Initial setup on DOM content loaded
document.addEventListener('DOMContentLoaded', () => {
console.log('DOM content loaded');
applyStoredTheme(); // Apply the stored theme or system preference
createThemeToggleButton(); // Create the theme toggle button and attach to nav
// Initial routing setup (if using navigation in your app)
router();
console.log('Initial setup completed');
document.addEventListener("DOMContentLoaded", () => {
console.log("DOM content loaded");
applyStoredTheme(); // Apply the stored theme or system preference
createThemeToggleButton(); // Create the theme toggle button and attach to nav
// Initial routing setup (if using navigation in your app)
router();
console.log("Initial setup completed");
});

// Import your components for routing (if necessary)
import { Home, About, Settings, NotFound } from './components.js';
import { Home, About, Settings, NotFound } from "./components.js";

// Define routes and their corresponding components (if necessary)
const routes = {
'/': Home,
'/about': About,
'/settings': Settings,
"/": Home,
"/about": About,
"/settings": Settings,
};

// Function to handle navigation (if necessary)
function navigateTo(url) {
console.log('Navigating to:', url);
history.pushState(null, null, url);
router();
history.pushState(null, null, url);
router();
}

// Router function to render components based on the current URL
function router() {
console.log('Router function called');
const path = window.location.pathname;
console.log('Current path:', path);
const route = routes[path] || NotFound;
route();
const path = window.location.pathname;
const route = routes[path] || NotFound;
route();
}

// Event delegation for link clicks (if necessary)
document.addEventListener('click', (e) => {
if (e.target.matches('[data-link]')) {
console.log('Link clicked:', e.target.href);
e.preventDefault();
navigateTo(e.target.href);
}
// Event delegation for link clicks
document.addEventListener("click", (e) => {
if (e.target.matches("[data-link]")) {
e.preventDefault();
navigateTo(e.target.href);
}
});

// Listen to popstate event (back/forward navigation) (if necessary)
window.addEventListener('popstate', router);
// Listen to popstate event (back/forward navigation)
window.addEventListener("popstate", router);

console.log('Script loaded');
// Initial call to router to render the correct component on page load
document.addEventListener("DOMContentLoaded", router);
25 changes: 25 additions & 0 deletions javascript/dwa-starter-vanillajs-vite/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "dwa-starter-vanillajs-vite",
"display": "standalone",
"scope": "/",
"start_url": "/index.html",
"theme_color": "#ffffff",
"background_color": "#ffffff",
"icons": [
{
"purpose": "maskable",
"sizes": "512x512",
"src": "./public/maskable-icon-512x512.png",
"type": "image/png"
},
{
"purpose": "any",
"sizes": "512x512",
"src": "./public/pwa-512x512.png",
"type": "image/png"
}
],
"orientation": "any",
"dir": "auto",
"lang": "en-US"
}
6 changes: 5 additions & 1 deletion javascript/dwa-starter-vanillajs-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@
"jsdom": "^25.0.1",
"playwright": "^1.47.2",
"postcss": "^8.4.47",
"serwist": "^9.0.9",
"tailwindcss": "^3.4.13",
"vite": "^5.4.1",
"vitest": "^2.1.2"
},
"packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added serwist/next dependency

"packageManager": "[email protected]+sha512.22721b3a11f81661ae1ec68ce1a7b879425a1ca5b991c975b074ac220b187ce56c708fe5db69f4c962c989452eee76c82877f4ee80f474cebd61ee13461b6228",
"dependencies": {
"@serwist/next": "^9.0.9"
}
}
42 changes: 21 additions & 21 deletions javascript/dwa-starter-vanillajs-vite/playwright.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defineConfig, devices } from '@playwright/test';
import { defineConfig, devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
Expand All @@ -9,15 +9,15 @@ import { defineConfig, devices } from '@playwright/test';
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './tests',
testDir: "./tests",
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
timeout: 5000,
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
Expand All @@ -26,41 +26,41 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:5173',
baseURL: "http://localhost:5173",

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',
trace: "on-first-retry",

/* Only on CI systems run the tests headless */
headless: !!process.env.CI
headless: !!process.env.CI,
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
name: "chromium",
use: {
...devices['Desktop Chrome']
}
...devices["Desktop Chrome"],
},
},
{
name: 'firefox',
name: "firefox",
use: {
...devices['Desktop Firefox']
}
...devices["Desktop Firefox"],
},
},
{
name: 'webkit',
name: "webkit",
use: {
...devices['Desktop Safari']
}
}
...devices["Desktop Safari"],
},
},

/* Test against mobile viewports. */
// {
Expand Down Expand Up @@ -101,9 +101,9 @@ export default defineConfig({
* Use the preview server on CI for more realistic testing.
* Playwright will re-use the local server if there is already a dev-server running.
*/
command: 'pnpm run dev',
url: 'http://localhost:5173', // Adjust this if your dev server uses a different port
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to npm because i am using npm and the testcases were failing

command: "npm run dev",
url: "http://localhost:5173", // Adjust this if your dev server uses a different port
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000, // 120 seconds
}
})
},
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Loading