diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4bb53b7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "svg.preview.background": "editor" +} \ No newline at end of file diff --git a/assets/sounds/Different.mp3 b/assets/sounds/Different.mp3 new file mode 100644 index 0000000..ba4c9ed Binary files /dev/null and b/assets/sounds/Different.mp3 differ diff --git a/assets/sounds/login.mp3 b/assets/sounds/login.mp3 new file mode 100644 index 0000000..a430b76 Binary files /dev/null and b/assets/sounds/login.mp3 differ diff --git a/assets/wallpapers/credits.txt b/assets/wallpapers/credits.txt index f30390d..76bcb51 100644 --- a/assets/wallpapers/credits.txt +++ b/assets/wallpapers/credits.txt @@ -5,4 +5,5 @@ Richard Horvath on Unsplash (https://unsplash.com/@ricvath) Li Zhang on Unsplash (https://unsplash.com/@sunx) LekoArts on Unsplash (https://unsplash.com/@lekoarts) Daniel Menakhovsky on Unsplash (https://unsplash.com/@menakhovsky) -Shubham Dhage on Unsplash (https://unsplash.com/@theshubhamdhage) \ No newline at end of file +Shubham Dhage on Unsplash (https://unsplash.com/@theshubhamdhage) +Sendlinger_Fotografie from Pixabay (https://pixabay.com/users/sendlinger_fotografie-28774278/) \ No newline at end of file diff --git a/assets/wallpapers/lake next to mountains.jpg b/assets/wallpapers/lake next to mountains.jpg new file mode 100644 index 0000000..d3b73f2 Binary files /dev/null and b/assets/wallpapers/lake next to mountains.jpg differ diff --git a/assets/wallpapers/macos.png b/assets/wallpapers/macos.png new file mode 100644 index 0000000..4637b32 Binary files /dev/null and b/assets/wallpapers/macos.png differ diff --git a/index.html b/index.html index 3b87294..0753b1e 100644 --- a/index.html +++ b/index.html @@ -1,6 +1,6 @@ - + AzuOS diff --git a/index.py b/index.py index 10ad32d..266d63b 100644 --- a/index.py +++ b/index.py @@ -2,9 +2,78 @@ import subprocess import os import pathlib +# Hardware and Platform Related Imports +import psutil, cpuinfo +import platform from screeninfo import get_monitors +import base64 class Api: + def collect_platform_info(self): + platform_info = { + "system": platform.system(), + "node": platform.node(), + "release": platform.release(), + "version": platform.version(), + "machine": platform.machine(), + "processor": platform.processor(), + "architecture": platform.architecture(), + "python_version": platform.python_version(), + "python_implementation": platform.python_implementation(), + "python_build": platform.python_build(), + "python_compiler": platform.python_compiler(), + "uname": platform.uname()._asdict() + } + try: + platform_info["platform"] = platform.platform() + except Exception as e: + platform_info["platform"] = f"Error: {str(e)}" + + return platform_info + + def memory_data(self): + return { + "memoryTotal": round(psutil.virtual_memory().total / (1024**3), 2), + "memoryTotalRaw": psutil.virtual_memory().total, + "memoryAvailable": round(psutil.virtual_memory().available / (1024**3), 2), + "memoryAvailableRaw": psutil.virtual_memory().available, + "memoryUsed": round(psutil.virtual_memory().used / (1024**3), 2), + "memoryUsedRaw": psutil.virtual_memory().used, + "memoryFree": round(psutil.virtual_memory().free / (1024 ** 3), 2), + "memoryFreeRaw": psutil.virtual_memory().free + } + + def cpu_data(self): + return cpuinfo.get_cpu_info() + + def drive_data(self): + drives = [] + for partition in psutil.disk_partitions(): + try: + usage = psutil.disk_usage(partition.mountpoint) + drives.append({ + "device": partition.device, + "mountpoint": partition.mountpoint, + "totalSpace": round(usage.total / (1024**3), 2), + "usedSpace": round(usage.used / (1024**3), 2), + "freeSpace": round(usage.free / (1024**3), 2), + "totalSpaceRaw": usage.total / (1024**3), + "usedSpaceRaw": usage.used / (1024**3), + "freeSpaceRaw": usage.free / (1024**3), + }) + except PermissionError: + pass + + return drives + + def resolve_full_path(self, path): + return str(pathlib.Path(path).expanduser()) + + def convert_image_to_data_url(self, image_path): + with open(image_path, "rb") as image_file: + encoded_string = base64.b64encode(image_file.read()).decode('utf-8') + return f"data:image/png;base64,{encoded_string}" + def get_wifi_networks(self): print('not implemented') @@ -42,6 +111,17 @@ def fetch_file(self, type, path): return 'file://' + os.path.expanduser(path) else: return 'file://' + path + + def save_file(self, path, content): + if type == "plain": + if path.startswith("~/"): + # Open the file in write mode + with open(os.path.expanduser(path), 'w') as file: + file.write(content) + else: + with open(path, 'w') as file: + file.write(content) + primaryMonitor = next((m for m in get_monitors() if m.is_primary), None) diff --git a/libs/api/systeminfo.js b/libs/api/systeminfo.js index 6eef840..2530219 100644 --- a/libs/api/systeminfo.js +++ b/libs/api/systeminfo.js @@ -28,6 +28,8 @@ azuapi.call = (originalCall => { "height": heightRatio } } + } else if (name === 'platinfo') { + return pywebview.api.collect_platform_info(); } } diff --git a/libs/loadmodule.js b/libs/loadmodule.js index b8fe859..fbc9648 100644 --- a/libs/loadmodule.js +++ b/libs/loadmodule.js @@ -191,4 +191,35 @@ function unloadCSS(file) { } else { console.error(`[CSS Injector] CSS file not found: ${file}`); } -} \ No newline at end of file +} + +function unloadRawPathCSS(file) { + const link = document.querySelector(`link[href="${file}"]`); + if (link) { + link.remove(); + console.log(`[CSS Injector] Removed CSS file: ${file}`); + } else { + console.error(`[CSS Injector] CSS file not found: ${file}`); + } +} + +// function loadTheme(file) { +// const themesPath = "themes/"; +// const link = document.querySelector(`link[href="${themesPath + file}"]`); +// if (!link) { +// loadRawPathCSS(themesPath + file); +// } else { +// console.error(`[CSS Injector] Theme already loaded: ${file}`) +// } +// } + +// function reloadTheme(file) { +// const themesPath = "themes/"; +// unloadRawPathCSS(themesPath + file); +// loadRawPathCSS(themesPath + file); +// } + +// function unloadTheme(file) { +// const themesPath = "themes/"; +// unloadRawPathCSS(themesPath + file); +// } \ No newline at end of file diff --git a/libs/system/extensionlink.js b/libs/system/extensionlink.js index d64b8ff..ee2de52 100644 --- a/libs/system/extensionlink.js +++ b/libs/system/extensionlink.js @@ -4,14 +4,18 @@ Opens applications corresponding to their file extension */ -var extension = document.currentScript.getAttribute('script-arguments').split('.').pop(); +var extension = document.currentScript.getAttribute('script-arguments').split('.').pop().toLowerCase(); var azutext = ['txt', 'json', 'md'] +var azuimg = ['apng', 'png', 'jpg', 'jpeg', 'gif', 'ico', 'cur', 'jfif', 'pjpeg', 'pjp', 'svg'] var scriptfile = ['js'] if (azutext.includes(extension)) { loadPackage('apps:azutext.js', document.currentScript.getAttribute('script-arguments')) console.log(`[Extension Link] Opening ${document.currentScript.getAttribute('script-arguments')} in AzuText`) -}; +} else if (azuimg.includes(extension)) { + loadPackage('apps:azuimg.js', document.currentScript.getAttribute('script-arguments')) + console.log(`[Extension Link] Opening ${document.currentScript.getAttribute('script-arguments')} in AzuImage`) +} if (scriptfile.includes(extension)) { loadScript(document.currentScript.getAttribute('script-arguments')) diff --git a/libs/system/sdk.js b/libs/system/sdk.js index 7a12545..ad63b18 100644 --- a/libs/system/sdk.js +++ b/libs/system/sdk.js @@ -78,7 +78,7 @@ const win = { }; const element = { - create: (type, innerHTML, codename) => { + create: (type, innerHTML, codename, manualIsElementOverwrite = false) => { return new Promise((resolve) => { const elm = document.createElement(type); elm.innerHTML = innerHTML; @@ -98,6 +98,34 @@ const element = { elm.id = (id); return elementObject; }, + display: (display) => { + elm.style.display = display; + return elementObject; + }, + flex: () => { + elm.style.display = 'flex'; + return elementObject; + }, + gap: (gap) => { + elm.style.gap = gap; + return elementObject; + }, + objectfit: (type) => { + elm.style.objectFit = type; + return elementObject; + }, + objectFit: (type) => { + elm.style.objectFit = type; + return elementObject; + }, + horizontal: () => { + elm.style.flexDirection = 'row'; + return elementObject; + }, + vertical: () => { + elm.style.flexDirection = 'column'; + return elementObject; + }, align: (alignment) => { elm.classList.add('__azuos-sdk-align-center'); return elementObject; @@ -292,6 +320,22 @@ const element = { elm.style.marginRight = right; return elementObject; }, + marginTop: (top) => { + elm.style.marginTop = top; + return elementObject; + }, + marginLeft: (left) => { + elm.style.marginLeft = left; + return elementObject; + }, + marginBottom: (bottom) => { + elm.style.marginBottom = bottom; + return elementObject; + }, + marginRight: (right) => { + elm.style.marginRight = right; + return elementObject; + }, radius: (radius) => { elm.style.borderRadius = radius; return elementObject; @@ -413,6 +457,9 @@ const element = { // } elm.setAttribute("codename", codename); + if (!manualIsElementOverwrite) { + elm.setAttribute("isElement", ""); + } resolve(elementObject); // console.log(elm.classList) @@ -420,6 +467,17 @@ const element = { elm.classList.add('__azuos-button-small'); } }); + }, + get: (codename, returnAsJSON = false) => { + const elm = document.querySelector(`[codename="${codename}"]`); + + if (!elm) { + return returnAsJSON ? { element: null, hasAttribute: false } : [null, false]; + } + + const hasAttr = elm.hasAttribute("isElement"); + + return returnAsJSON ? { element: elm, hasAttribute: hasAttr } : [elm, hasAttr]; } }; @@ -470,7 +528,6 @@ const math = { if (point1.length !== point2.length) throw new Error("Points must have the same dimension."); return Math.sqrt(point1.reduce((sum, _, i) => sum + (point1[i] - point2[i]) ** 2, 0)); }, - erf: (x) => { const sign = Math.sign(x); const absX = Math.abs(x); @@ -478,11 +535,53 @@ const math = { const a1 = 0.254829592, a2 = -0.284496736, a3 = 1.421413741, a4 = -1.453152027, a5 = 1.061405429; const poly = t * (a1 + t * (a2 + t * (a3 + t * (a4 + t * a5)))); return sign * (1 - poly * Math.exp(-absX * absX)); - } + }, + circleSurfaceArea: (radius) => { + return Math.pow(radius, 2) * Math.PI; + }, + circleCircumference: (diameter) => { + return diameter * Math.PI; + }, + pyramidVolume: (baseLength, height) => { + const baseArea = baseLength * baseLength; + return (1/3) * baseArea * height; + }, + pyramidSurfaceArea: (baseLength, sideLength) => { + // Assuming a square base pyramid + const baseArea = baseLength * baseLength; + const slantHeight = Math.sqrt(Math.pow(sideLength/2, 2) + Math.pow(height, 2)); // height needs to be passed as an argument + const lateralArea = 2 * baseLength * slantHeight; + return baseArea + lateralArea; + }, + sphereVolume: (radius) => { + return (4/3) * Math.PI * Math.pow(radius, 3); + }, + sphereSurfaceArea: (radius) => { + return 4 * Math.PI * Math.pow(radius, 2); + }, + cylinderVolume: (radius, height) => { + return Math.PI * Math.pow(radius, 2) * height; + }, + cylinderSurfaceArea: (radius, height) => { + return 2 * Math.PI * radius * (radius + height); + }, + coneVolume: (radius, height) => { + return (1/3) * Math.PI * Math.pow(radius, 2) * height; + }, + coneSurfaceArea: (radius, height) => { + const slantHeight = Math.sqrt(Math.pow(radius, 2) + Math.pow(height, 2)); + return Math.PI * radius * (radius + slantHeight); + }, + cuboidVolume: (length, width, height) => { + return length * width * height; + }, + cuboidSurfaceArea: (length, width, height) => { + return 2 * (length * width + length * height + width * height); + } }; -// const system = { +const system = { // version: () => { // return 8; // }, @@ -495,25 +594,25 @@ const math = { // maker: () => { // return "AzuSystem"; // }, -// screen: () => { -// const screen = window.screen; -// const divisor = math.gdc(screen.width, screen.height); -// const widthRatio = screen.width / divisor; -// const heightRatio = screen.height / divisor; + screen: () => { + const screen = window.screen; + const divisor = math.gdc(screen.width, screen.height); + const widthRatio = screen.width / divisor; + const heightRatio = screen.height / divisor; -// return { -// "width": screen.width, -// "height": screen.height, -// "colorDepth": screen.colorDepth, -// "orientation": screen.orientation, -// "pixelDepth": screen.pixelDepth, -// "aspectRatio": { -// "width": widthRatio, -// "height": heightRatio -// } -// } -// } -// } + return { + "width": screen.width, + "height": screen.height, + "colorDepth": screen.colorDepth, + "orientation": screen.orientation, + "pixelDepth": screen.pixelDepth, + "aspectRatio": { + "width": widthRatio, + "height": heightRatio + } + } + } +} const webwin = { create: (title, url, codename) => { @@ -607,12 +706,41 @@ const strings = { let greeting; if (currentHour >= 5 && currentHour < 12) { - greeting = "Good Morning"; + greeting = "Good morning"; } else if (currentHour >= 12 && currentHour < 18) { - greeting = "Good Afternoon"; + greeting = "Good afternoon"; + } else if (currentHour >= 18 && currentHour < 22) { + greeting = "Good evening"; } else { - greeting = "Good Evening"; + greeting = "Good night"; } return greeting; - } + }, + trim_to_length: (str, maxLength) => { + if (str.length > maxLength) { + return str.slice(0, maxLength) + "..."; // Keep only the first `maxLength` characters + } + return str; // Return the string unchanged if within the limit + } +} + +const audio = { + load: (file) => { + return new Audio(file); + }, + setProgress: (audiosource, progress) => { + audiosource.currentTime = progress; + } +} + +const soundsPath = `assets/sounds/`; +const sounds = { + debugsound: () => { + let sfx = audio.load(soundsPath + "Different.mp3"); + sfx.play(); + }, + play: (sound) => { + let sfx = audio.load(soundsPath + sound + ".mp3"); + sfx.play(); + } } \ No newline at end of file diff --git a/libs/system/thememanager.js b/libs/system/thememanager.js index efba17d..f293dbd 100644 --- a/libs/system/thememanager.js +++ b/libs/system/thememanager.js @@ -4,13 +4,18 @@ */ function loadTheme(file) { - var link = document.createElement('link'); - link.rel = 'stylesheet'; - link.type = 'text/css'; - link.href = `themes/${file}`; + const existing = document.querySelector(`link[href="themes/${file}"]`); + if (!existing) { + var link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = `themes/${file}`; - document.head.appendChild(link); - console.log(`[Theme Manager] Imported '${file}'`) + document.head.appendChild(link); + console.log(`[Theme Manager] Imported '${file}'`); + } else { + console.error(`[Theme Manager] Failed to import '${file}': Theme already loaded.`); + } } function unloadTheme(file) { diff --git a/pkgs/apps/azuimg.js b/pkgs/apps/azuimg.js new file mode 100644 index 0000000..dabc9df --- /dev/null +++ b/pkgs/apps/azuimg.js @@ -0,0 +1,30 @@ +var filename = document.currentScript.getAttribute('script-arguments') +// let textdata; + +win.create('AzuImage', "azuimgwin").then(win => win + .setWidth(700) + .setHeight(500) + .confirm() +); +// element.create('p', 'Click on an image file on the desktop to preview it.', 'azuimgwaittoload').then(elm => elm +// .window('azuimgwin') +// ); + +if (filename) { + var b64image = "" + var file = pywebview.api.resolve_full_path(filename); + + file.then(result => { + b64image = pywebview.api.convert_image_to_data_url(result); + b64image.then(result => { + element.create('img', '', 'azuimgpreview').then(elm => elm + .window('azuimgwin') + .position('fixed') + .attribute("width", "100%") + .attribute("height", "100%") + .objectfit('contain') + .src(result) + ); + }) + }); +} \ No newline at end of file diff --git a/pkgs/apps/azutext.js b/pkgs/apps/azutext.js index 6d3396e..965c193 100644 --- a/pkgs/apps/azutext.js +++ b/pkgs/apps/azutext.js @@ -3,58 +3,40 @@ var styling = (` font-family: 'Inter'; resize: none; box-sizing: border-box; + color: var(--azu-text-color); `) var filename = document.currentScript.getAttribute('script-arguments') // let textdata; +win.create('AzuText', "azutextwin").then(win => win + .setWidth(700) + .setHeight(500) + .confirm() +); +element.create('textarea', '', 'azutextinput').then(elm => elm + .window('azutextwin') + .css(styling) + .position('fixed') + .width('calc(100% - 6px)') + .height('calc(100% - 6px)') + .placeholder('Write Something :3') + .align('center') + .attribute('wrap', 'soft') + .color('white') + .backgroundcolor('transparent') + .border('none') + .outline('none') + .padding('20px') +); + if (filename) { - win.create(`${filename} - AzuText`, "root").then(win => win - .setWidth(700) - .setHeight(500) - .confirm() - ); fetch_file(filename, "plain") .then(result => { - element.create('textarea', result, '').then(elm => elm - .window('root') - .css(styling) - .position('fixed') - .width('calc(100% - 6px)') - .height('calc(100% - 6px)') - .placeholder('Write Something :3') - .align('center') - .attribute('wrap', 'soft') - .color('white') - .backgroundcolor('transparent') - .border('none') - .outline('none') - .padding('20px') - ); + let textinput = element.get('azutextinput'); + textinput[0].value = result; }) .catch(error => { console.error("[AzuText] Error:", error); }); -} else { - win.create('AzuText', "root").then(win => win - .setWidth(700) - .setHeight(500) - .confirm() - ); - - element.create('textarea', '', '').then(elm => elm - .window('root') - .css(styling) - .position('fixed') - .width('calc(100% - 6px)') - .height('calc(100% - 6px)') - .placeholder('Write Something :3') - .align('center') - .attribute('wrap', 'soft') - .color('white') - .backgroundcolor('transparent') - .border('none') - .outline('none') - .padding('20px') - ); } \ No newline at end of file diff --git a/pkgs/apps/desktop.js b/pkgs/apps/desktop.js index d71f136..87b0f32 100644 --- a/pkgs/apps/desktop.js +++ b/pkgs/apps/desktop.js @@ -6,7 +6,13 @@ loadCSS('index.css'); loadCSS('button.css'); // loadTheme('default-theme.css'); -loadTheme('dark-mode.css'); +// loadTheme('dark-mode.css'); +loadTheme('light-mode.css'); +loadCSS('notification.css'); + +// Load all the individial CSS files for elements. +loadCSS('ui/button.css'); + unloadCSS('boot.css'); unloadCSS('login.css'); unloadPackage('system:bootscreen.js'); @@ -15,6 +21,7 @@ loadPackage('apps:desktop/wallpaper.js'); loadPackage('apps:desktop/watermark.js'); loadPackage('apps:desktop/taskbar.js'); loadPackage('apps:desktop/icons.js'); +sounds.play("login") // windowManager('start'); diff --git a/pkgs/apps/desktop/hideicons.js b/pkgs/apps/desktop/hideicons.js new file mode 100644 index 0000000..e69de29 diff --git a/pkgs/apps/desktop/icons.js b/pkgs/apps/desktop/icons.js index 12325cb..2a469ad 100644 --- a/pkgs/apps/desktop/icons.js +++ b/pkgs/apps/desktop/icons.js @@ -3,6 +3,27 @@ Written by: MTSyntho @ AzuSystem 2024 */ +let platform_info = {}; + +try { + platform_info = azuapi.call("platinfo", ""); +} catch (error) { + platform_info = { + "system": null, + "node": null, + "release": null, + "version": null, + "machine": null, + "processor": null, + "architecture": null, + "python_version": null, + "python_implementation": null, + "python_build": null, + "python_compiler": null, + "uname": null, + } +} + // Create the container for all desktop icons const desktopIcons = document.createElement('div'); desktopIcons.className = 'desktop-icons'; @@ -68,6 +89,7 @@ addDesktopApp('SDK Test', 'assets/icons/exclamation.svg', 'apps:dynamic-test.js' addDesktopApp('About', 'assets/icons/computer.svg', 'apps:sysver.js'); addDesktopApp('VirtualPC', 'assets/icons/questionmark.svg', 'apps:virtualpc.js'); addDesktopApp('AzuText', 'assets/icons/questionmark.svg', 'apps:azutext.js'); +addDesktopApp('Hardware', 'assets/icons/questionmark.svg', 'apps:hwinfo.js'); addDesktopApp('AzuTheme', 'assets/icons/questionmark.svg', 'settings:azutheme.js'); addDesktopApp('Video Demo', 'assets/icons/questionmark.svg', 'apps:videodemo.js'); addDesktopApp('AzuFile', 'assets/icons/questionmark.svg', 'apps:azufile.js'); @@ -77,7 +99,15 @@ addDesktopApp('AzuFile', 'assets/icons/questionmark.svg', 'apps:azufile.js'); fetch_directory('~/Desktop').then(([files, folders]) => { // Process files files.forEach(file => { - addDesktopFiles(file, 'assets/icons/questionmark.svg'); + // if (file.endsWith(".txt")) { + + // } else { + + // } + + if (platform_info !== "Windows" && !(file.endsWith(".lnk") || file.endsWith(".url")) || !(file.startsWith(".")) ) { + addDesktopFiles(file, 'assets/icons/questionmark.svg'); + } }); folders.forEach(folder => { diff --git a/pkgs/apps/desktop/taskbar.js b/pkgs/apps/desktop/taskbar.js index f20ab08..b12d338 100644 --- a/pkgs/apps/desktop/taskbar.js +++ b/pkgs/apps/desktop/taskbar.js @@ -4,30 +4,30 @@ */ const taskbarcss = (` - background-color: var(--azu-taskbar-background); - outline: var(--azu-taskbar-outline); - /*border-radius: 4px;*/ - position: fixed; - bottom: 0px; - width: var(--azu-taskbar-width); - margin: 15px; - height: 45px; - padding: 0px; - left: 0; - right: 0; - margin-left: auto; - margin-right: auto; - box-shadow: var(--azu-taskbar-shadow); - display: flex; - z-index: 50; - backdrop-filter: var(--azu-taskbar-blur); - -webkit-backdrop-filter: var(--azu-taskbar-blur); - border-radius: var(--azu-taskbar-border-radius); - display: flex; - flex-direction: row; - align-items: center; - justify-content: left; - text-align: center; + background-color: var(--azu-taskbar-background); + outline: var(--azu-taskbar-outline); + /*border-radius: 4px;*/ + position: fixed; + bottom: 0px; + width: var(--azu-taskbar-width); + margin: 15px; + height: 45px; + padding: 0px; + left: 0; + right: 0; + margin-left: auto; + margin-right: auto; + box-shadow: var(--azu-taskbar-shadow); + display: flex; + z-index: 50; + backdrop-filter: var(--azu-taskbar-blur); + -webkit-backdrop-filter: var(--azu-taskbar-blur); + border-radius: var(--azu-taskbar-border-radius); + display: flex; + flex-direction: row; + align-items: center; + justify-content: left; + text-align: center; `) const taskbarcomponent = (` @@ -79,12 +79,11 @@ const taskbarprocesses = (` width: calc(100% - 180px); `) -element.create('div', '', 'taskbar').then(elm => elm +element.create('div', '', 'taskbar', true).then(elm => elm .css(taskbarcss) .parent('desktop') ); - // Start Button element.create('button', '', 'start-btn').then(elm => elm .css(taskbarcomponent + taskbarstart) diff --git a/pkgs/apps/hwinfo.js b/pkgs/apps/hwinfo.js new file mode 100644 index 0000000..b8915c0 --- /dev/null +++ b/pkgs/apps/hwinfo.js @@ -0,0 +1,82 @@ +var cpu_data = pywebview.api.cpu_data() +var memory_data = pywebview.api.memory_data() +var drive_data = pywebview.api.drive_data() + + +win.create('Hardware Info', 'hwinfowin').then(win => win + .setWidth(640) + .setHeight(360) + .confirm() +) + +element.create('div', '', 'hwinfodiv').then(elm => elm + .window('hwinfowin') + .flex() + .gap("8px") + .vertical() + .padding('20px') +); + +element.create('h1', `Hardware Info`, '').then(elm => elm + .margin(0) + .parent("hwinfodiv") +) + +element.create('p', 'Loading...', 'loadingtexthwinfo').then(elm => elm + .margin(0) + .parent("hwinfodiv") +); + +cpu_data.then(result => { + element.get('loadingtexthwinfo')[0].remove() + element.create('h2', 'Core Hardware', '').then(elm => elm + .margin(0) + .parent("hwinfodiv") + ); + element.create('p', 'CPU: ' + result.brand_raw, '').then(elm => elm + .margin(0) + .parent("hwinfodiv") + ); + memory_data.then(result => { + element.create('p', 'Total Memory: ' + result.memoryTotal + " GB (" + result.memoryUsed + " GB Used, " + result.memoryAvailable + " GB available)", '').then(elm => elm + .margin(0) + .parent("hwinfodiv") + ); + element.create('h2', 'Drives', '').then(elm => elm + .margintop("8px") + .marginBottom(0) + .parent("hwinfodiv") + ); + drive_data.then(result => { + for (let drive of result) { + element.create('div', '', "drvInfo" + drive.device.slice(0, 1) + "div").then(elm => elm + .flex() + .backgroundcolor("var(--azu-button-bg)") + .vertical() + .gap("4px") + .padding("8px") + .radius("8px") + .parent("hwinfodiv") + ) + element.create('p', drive.device + " (" + drive.usedSpace + "GB / " + drive.totalSpace + "GB)", '').then(elm => elm + .margin(0) + .parent("drvInfo" + drive.device.slice(0, 1) + "div") + ); + element.create('div', '', "drv" + drive.device.slice(0, 1) + 'progdiv').then(elm => elm + .height("8px") + .radius("4px") + .backgroundcolor("var(--azu-button-bg)") + .parent("drvInfo" + drive.device.slice(0, 1) + "div") + ) + element.create('div', '', '').then(elm => elm + .backgroundcolor("var(--azu-button-text)") + .position("relative") + .height("8px") + .radius("4px") + .width(((drive.usedSpaceRaw / drive.totalSpaceRaw)*100).toString() + "%") + .parent("drv" + drive.device.slice(0, 1) + 'progdiv') + ) + } + }); + }); +}); diff --git a/pkgs/apps/sysver.js b/pkgs/apps/sysver.js index 2642028..d827040 100644 --- a/pkgs/apps/sysver.js +++ b/pkgs/apps/sysver.js @@ -9,7 +9,7 @@ var osname = azuapi.call('sysinfo', 'os') var osver = azuapi.call('sysinfo', 'version') var osdev = azuapi.call('sysinfo', 'developer') -win.create("About " + osname, "root").then(win => win +win.create("About " + osname, "sysverwin").then(win => win .setWidth(700) .setHeight(500) .confirm() @@ -17,7 +17,7 @@ win.create("About " + osname, "root").then(win => win // Background element.create('div', '', '').then(elm => elm - .window('root') + .window('sysverwin') .width('220px') .height('100%') .position('fixed') @@ -33,7 +33,7 @@ element.create('div', '', '').then(elm => elm ); element.create('div', '', 'sidebar').then(elm => elm - .window('root') + .window('sysverwin') .width('220px') .height('100%') .position('fixed') @@ -42,7 +42,7 @@ element.create('div', '', 'sidebar').then(elm => elm ); element.create('div', '', 'contents').then(elm => elm - .window('root') + .window('sysverwin') .width('calc(100% - 240px)') .height('100%') .position('fixed') diff --git a/pkgs/settings/azutheme.js b/pkgs/settings/azutheme.js index 97f6dcf..0b362a1 100644 --- a/pkgs/settings/azutheme.js +++ b/pkgs/settings/azutheme.js @@ -47,6 +47,30 @@ element.create('div', '', '').then(elm => elm element.create('button', 'AzuOS Default', '').then(elm => elm .parent('azuthemediv') - // .usesystemcss('false') - // .buttontype('large') -); \ No newline at end of file + .opacity(0.4) +) + +element.create('div', '', 'tempthemeswitch').then(elm => elm + .flex() + .gap("8px") + .horizontal() + .parent('azuthemediv') +) + +element.create('button', 'Light -> Dark', '').then(elm => elm + .attribute('onclick', `unloadTheme("light-mode.css"); + unloadCSS("index.css"); + loadTheme("dark-mode.css"); + loadCSS("index.css"); + `) + .parent('tempthemeswitch') +) + +element.create('button', 'Dark -> Light', '').then(elm => elm + .attribute('onclick', `unloadTheme("dark-mode.css"); + unloadCSS("index.css"); + loadTheme("light-mode.css"); + loadCSS("index.css"); + `) + .parent('tempthemeswitch') +) \ No newline at end of file diff --git a/pkgs/system/bootscreen.js b/pkgs/system/bootscreen.js index 6ebfd39..bd548f3 100644 --- a/pkgs/system/bootscreen.js +++ b/pkgs/system/bootscreen.js @@ -30,15 +30,25 @@ if (__skipBoot === true) { let greeting; if (currentHour >= 5 && currentHour < 12) { - greeting = "Good Morning"; + greeting = "Good morning"; } else if (currentHour >= 12 && currentHour < 18) { - greeting = "Good Afternoon"; + greeting = "Good afternoon"; + } else if (currentHour >= 18 && currentHour < 22) { + greeting = "Good evening"; } else { - greeting = "Good Evening"; + greeting = "Good night"; } document.getElementById("welcometextobject").innerHTML = greeting; + // ! Doesn't work due to autoplay. Boot.mp3 renamed to login.mp3 + // let sfx = new Audio("assets/sounds/boot.mp3"); + // sfx.play().then(() => { + // console.log("Audio played successfully!"); + // }).catch((error) => { + // console.error("Autoplay was blocked:", error); + // }); + setTimeout(function() { welcome.classList.remove("fadein"); welcome.classList.add("fadeout"); diff --git a/stylesheets/index.css b/stylesheets/index.css index 3b1dbfe..8d5118e 100644 --- a/stylesheets/index.css +++ b/stylesheets/index.css @@ -1,3 +1,7 @@ +:root { + --transition-quick-out: cubic-bezier(0, 0, 0, 1) 150ms; +} + body { background-color: var(--azu-color-background); } diff --git a/stylesheets/notification.css b/stylesheets/notification.css new file mode 100644 index 0000000..4217dae --- /dev/null +++ b/stylesheets/notification.css @@ -0,0 +1,33 @@ +@keyframes notification-in { + from { + right: -400px; + opacity: 0; + pointer-events: none; + } + to { + right: 0px; + opacity: 1; + pointer-events: all; + } + } + + @keyframes notification-out { + from { + right: 0px; + opacity: 1; + pointer-events: all; + } + to { + right: -400px; + opacity: 0; + pointer-events: none; + } + } + + .__azuos-notification-in { + animation: notification-in 0.2s ease-out forwards; + } + + .__azuos-notification-out { + animation: notification-out 0.2s ease-in forwards; + } \ No newline at end of file diff --git a/stylesheets/ui/button.css b/stylesheets/ui/button.css new file mode 100644 index 0000000..8567908 --- /dev/null +++ b/stylesheets/ui/button.css @@ -0,0 +1,18 @@ +button { + background: var(--azu-button-bg); + color: var(--azu-button-text); + outline: none; + border: none; + padding: 12px 16px; + border-radius: 10px; + transition: var(--transition-quick-out); +} + +button:hover { + background: var(--azu-button-bg-hover); +} + +button:active { + background: var(--azu-button-bg); + scale: 0.95; +} \ No newline at end of file diff --git a/themes/dark-mode.css b/themes/dark-mode.css index 0a0b471..75ef282 100644 --- a/themes/dark-mode.css +++ b/themes/dark-mode.css @@ -6,13 +6,19 @@ :root { --azu-color-background: hsla(0, 0, 30%); - --azu-wallpaper: url('../assets/wallpapers/dark waves.jpg'); + --azu-wallpaper: url('../assets/wallpapers/macos.png'); + /* --azu-wallpaper: url('https://cdn.discordapp.com/attachments/1146907940570284074/1317937509262688426/img28.jpg?ex=67608074&is=675f2ef4&hm=4a8762cc7a24b071c95f21b83fd0efa9f0e03105c40c07e3b8ffe7cfdefeefff&'); */ + --azu-startbutton: url('../assets/logo_white.svg'); --azu-color-main: hsla(270, 0%, 12%); --azu-color-light: hsla(270, 0%, 18%); --azu-color-shadow: hsla(0, 0%, 0%); --azu-button-color-main: hsla(270, 0%, 12%); --azu-text-color: hsla(0, 0%, 100%); + --azu-button-bg: hsla(0, 0%, 100%, 5%); + --azu-button-bg-hover: hsla(0, 0%, 100%, 10%); + --azu-button-text: hsla(0, 0%, 100%, 100%); + --azu-window-blur: blur(16px); --azu-window-background: hsla(269, 0%, 12%, 0.75); --azu-window-border-radius: 12px; @@ -20,7 +26,7 @@ --azu-window-shadow: 0px 0px 30px #000000; --azu-window-inner-background: hsla(267, 0%, 9%, 0.312); - --azu-taskbar-background: hsla(270, %, 12%, 75%); + --azu-taskbar-background: hsla(270, 0%, 12%, 75%); --azu-taskbar-outline: 1px solid rgba(255, 255, 255, 0.125); --azu-taskbar-width: 80%; --azu-taskbar-shadow: 0 0 10px 2px #000000cc; @@ -47,7 +53,7 @@ --azu-button-large-animation-duration: 0.2s; } -@keyframes notification-in { +/* @keyframes notification-in { from { right: -400px; opacity: 0; @@ -79,4 +85,4 @@ .__azuos-notification-out { animation: notification-out 0.2s ease-in forwards; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/themes/default-theme.css b/themes/default-theme.css index f32782c..13d6a53 100644 --- a/themes/default-theme.css +++ b/themes/default-theme.css @@ -6,12 +6,17 @@ :root { --azu-color-background: hsla(270, 35%, 7%); --azu-wallpaper: url('../assets/wallpapers/palm tree near dome.jpg'); + --azu-startbutton: url('../assets/logo_white.svg'); --azu-color-main: hsla(270, 44%, 12%); --azu-color-light: hsla(270, 40%, 18%); --azu-color-shadow: hsla(0, 0%, 0%); --azu-button-color-main: hsla(270, 44%, 12%); --azu-text-color: hsla(0, 0%, 100%); + --azu-button-bg: hsla(0, 0%, 100%, 5%); + --azu-button-bg: hsla(0, 0%, 100%, 7%); + --azu-button-text: hsla(0, 0%, 100%, 100%); + --azu-window-blur: blur(16px) saturate(180%); --azu-window-background: rgba(30, 17, 44, 0.75); --azu-window-border-radius: 12px; @@ -27,7 +32,7 @@ --azu-taskbar-border-radius: 12px; } -@keyframes notification-in { +/* @keyframes notification-in { from { right: -400px; opacity: 0; @@ -59,4 +64,4 @@ .__azuos-notification-out { animation: notification-out 0.2s ease-in forwards; -} \ No newline at end of file +} */ \ No newline at end of file diff --git a/themes/light-mode.css b/themes/light-mode.css new file mode 100644 index 0000000..5a6dc62 --- /dev/null +++ b/themes/light-mode.css @@ -0,0 +1,35 @@ +/* + AzuOS Default Theme (Light) + Written By: MTSyntho @ AzuSystem 2024 + Your eyes are cooked :'3 +*/ + +:root { + --azu-color-background: hsla(0, 0%, 95%); /* Lighter background */ + --azu-wallpaper: url('../assets/wallpapers/blue\ pink\ 3d\ circles.jpg'); + /* --azu-wallpaper: url('https://media.discordapp.net/attachments/1146907940570284074/1317937507807133706/img25.jpg?ex=67608073&is=675f2ef3&hm=ad88d1fea608f4cf6acd71623f62d796cd2dba8e43fd031f30d1fb563c057170&=&format=webp'); */ + --azu-color-main: hsla(270, 0%, 18%); /* Lighter main color */ + --azu-color-light: hsla(270, 0%, 28%); /* Lighter secondary color */ + --azu-color-shadow: hsla(0, 0%, 80%); /* Lighter shadow */ + --azu-button-color-main: hsla(270, 0%, 20%); /* Lighter button color */ + --azu-text-color: hsla(0, 0%, 20%); /* Dark text on light background */ + + --azu-button-bg: hsla(0, 0%, 7%, 0.05); + --azu-button-bg-hover: hsla(0, 0%, 7%, 10%); + --azu-button-text: hsla(0, 0%, 7%, 100%); + + --azu-window-blur: blur(16px); + --azu-window-background: hsla(269, 0%, 98%, 0.75); /* Lighter window background */ + --azu-window-border-radius: 12px; + --azu-window-border: 1px solid rgba(0, 0, 0, 0.125); /* Lighter border */ + --azu-window-shadow: 0 0 10px 2px #00000022; + --azu-window-inner-background: hsla(267, 0%, 95%, 0.312); /* Lighter inner background */ + + --azu-taskbar-background: hsla(270, 0%, 88%, 75%); /* Lighter taskbar */ + --azu-taskbar-outline: 1px solid rgba(0, 0, 0, 0.125); /* Lighter outline */ + --azu-taskbar-width: 80%; + --azu-taskbar-shadow: 0 0 10px 2px #00000022; + --azu-taskbar-blur: blur(16px); + --azu-taskbar-border-radius: 12px; + } + \ No newline at end of file diff --git a/themes/light-theme.css b/themes/light-theme.css deleted file mode 100644 index 65b7c14..0000000 --- a/themes/light-theme.css +++ /dev/null @@ -1,15 +0,0 @@ -/* - AzuOS Default Theme (Light) - Written By: MTSyntho @ AzuSystem 2024 - Your eyes are cooked :'3 -*/ - -:root { - --azu-color-background: hsla(0, 0% 88.64%); - --azu-color-main: hsla(0, 0%, 100%); - --azu-color-light: hsla(0, 0%, 65%); - --azu-color-shadow: hsla(0, 0%, 0%); - --azu-taskbar-width: 80%; - --azu-button-color-main: hsla(0, 0%, 65%); - --azu-text-color: hsla(0, 0%, 0%); -} \ No newline at end of file