Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Chanomhub/APP
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.0.6
Choose a base ref
...
head repository: Chanomhub/APP
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 3 commits
  • 26 files changed
  • 1 contributor

Commits on Jun 14, 2024

  1. Add files via upload

    Chanomhub authored Jun 14, 2024
    Copy the full SHA
    5f2bfc5 View commit details

Commits on Jun 20, 2024

  1. desktop 0.0.7

    Chanomhub committed Jun 20, 2024
    Copy the full SHA
    837be1a View commit details
  2. desktop 0.0.7

    Chanomhub committed Jun 20, 2024
    Copy the full SHA
    f08be54 View commit details
Binary file added Desktop/chanomhub.icns
Binary file not shown.
Binary file added Desktop/chanomhub.ico
Binary file not shown.
Binary file added Desktop/chanomhub.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 43 additions & 0 deletions Desktop/downloadManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// /mnt/data/downloadManager.ts
import path from 'path';

interface Download {
id: string;
name: string;
status: 'completed' | 'paused';
}

const downloads: Download[] = [];

function getDownloads(): Download[] {
return downloads;
}

function addDownload(filePath: string): void {
downloads.push({
id: filePath,
name: path.basename(filePath),
status: 'completed'
});
}

function pauseDownload(id: string): void {
const download = downloads.find(d => d.id === id);
if (download) {
download.status = 'paused';
}
}

function cancelDownload(id: string): void {
const index = downloads.findIndex(d => d.id === id);
if (index !== -1) {
downloads.splice(index, 1);
}
}

export {
getDownloads,
addDownload,
pauseDownload,
cancelDownload
};
259 changes: 259 additions & 0 deletions Desktop/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
import { app, BrowserWindow, Menu, ipcMain, session } from 'electron';
import path from 'path';
import fs from 'fs';
import { exec } from 'child_process';
import { autoUpdater } from 'electron-updater';
import log from 'electron-log';
import i18next from 'i18next';
import Backend from 'i18next-electron-fs-backend';

interface Download {
id: string;
name: string;
item: Electron.DownloadItem;
progress: number;
}

autoUpdater.logger = log;
(autoUpdater.logger as any).transports.file.level = 'info';
log.info('App starting...');

let downloadPath = app.getPath('downloads');
let cachePath = path.join(downloadPath, 'cache');
let downloads: Download[] = [];

let win: BrowserWindow; // Declare win globally

i18next.use(Backend).init({
lng: 'en', // Default language
fallbackLng: 'en', // Fallback language
backend: {
loadPath: path.join(__dirname, 'locales/{{lng}}/translation.json'),
},
debug: true, // Set to false in production
}, (err, t) => {
if (err) {
log.error('i18next initialization failed', err);
} else {
log.info('i18next initialized');
createWindow();
}
});

app.on('ready', () => {
// Create the window once i18next is initialized
i18next.on('initialized', createWindow);
});

function createWindow(): void {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
partition: 'persist:chanomhub',
devTools: true // Ensure developer tools are enabled
},
});

win.loadURL('https://chanomhub.xyz/');
win.webContents.openDevTools(); // Open developer tools

const menuTemplate = [
{
label: i18next.t('menu.advancedSearch'),
submenu: [
{ label: i18next.t('menu.downloads'), click: () => { win.loadFile('downloads.html'); } },
{ label: i18next.t('menu.profile'), click: () => { win.loadURL('https://chanomhub.xyz/setting/'); } },
{ label: i18next.t('menu.home'), click: () => { win.loadURL('https://chanomhub.xyz/'); } },
{ label: i18next.t('menu.allGame'), click: () => { win.loadFile('all-game.html'); } },
{ label: i18next.t('menu.setting'), click: () => { win.loadFile('setting.html'); } },
],
},
];

const menu = Menu.buildFromTemplate(menuTemplate);
Menu.setApplicationMenu(menu);

setupIpcHandlers();
setupDownloadHandler();
}

function setupIpcHandlers() {
ipcMain.handle('get-folders', (): string[] => {
return fs.readdirSync(downloadPath).filter(file => fs.statSync(path.join(downloadPath, file)).isDirectory());
});

ipcMain.handle('open-folder', (event, folder: string): void => {
const folderPath = path.join(downloadPath, folder);
if (fs.existsSync(folderPath)) {
exec(`"${folderPath}"`, (error) => {
if (error) {
console.error(`Error opening folder: ${error}`);
}
});
}
});

ipcMain.handle('get-downloads', (): any[] => {
return downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
}));
});

ipcMain.handle('pause-download', (event, id: string): void => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.pause();
}
log.info(`Download paused: ${id}`);
});

ipcMain.handle('resume-download', (event, id: string): void => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.resume();
}
log.info(`Download resumed: ${id}`);
});

ipcMain.handle('cancel-download', (event, id: string): void => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.cancel();
}
log.info(`Download canceled: ${id}`);
});

ipcMain.handle('get-download-path', (): string => {
log.info(`Download path: ${downloadPath}`);
return downloadPath;
});

ipcMain.handle('set-download-path', (event, newPath: string): void => {
downloadPath = newPath;
cachePath = path.join(downloadPath, 'cache');
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath);
}
log.info(`Download path changed: ${downloadPath}`);
});

ipcMain.on('install-update', (): void => {
autoUpdater.quitAndInstall();
});
}

function setupDownloadHandler() {
session.defaultSession.on('will-download', (event, item: Electron.DownloadItem): void => {
const cacheFilePath = path.join(cachePath, item.getFilename());

if (fs.existsSync(cacheFilePath)) {
log.info(`File already in cache: ${item.getFilename()}`);
win.webContents.send('download-complete', {
id: item.getURL(),
name: item.getFilename(),
path: cacheFilePath,
});
return;
}

item.setSavePath(cacheFilePath);
log.info(`Download started: ${item.getFilename()}`);
const download: Download = {
id: item.getURL(),
name: item.getFilename(),
item,
progress: 0,
};
downloads.push(download);

item.on('done', (event, state) => {
if (state === 'completed') {
log.info(`Download completed: ${item.getFilename()}`);
} else {
log.error(`Download failed: ${state}`, item.getFilename());
}
downloads = downloads.filter(d => d.id !== item.getURL());
win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
});

item.on('updated', (event, state) => {
if (state === 'interrupted') {
log.info(`Download paused: ${item.getFilename()}`);
} else if (state === 'progressing') {
if (item.isPaused()) {
log.info(`Download paused: ${item.getFilename()}`);
} else {
const progress = Math.round((item.getReceivedBytes() / item.getTotalBytes()) * 100);
download.progress = progress;
win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
}
}
});

win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
});
}

app.whenReady().then((): void => {
createWindow();

let updateURL = `${app.getAppPath()}/releases/latest`;

if (process.platform === 'win32') {
updateURL += `/download/${app.getVersion()}/${app.getName()}-Setup-${app.getVersion()}.exe`;
} else if (process.platform === 'darwin') {
updateURL += `/download/${app.getVersion()}/${app.getName()}-${app.getVersion()}-${process.arch}.dmg`;
} else if (process.platform === 'linux') {
updateURL += `/download/${app.getVersion()}/${app.getName()}-${app.getVersion()}-${process.arch}.deb`;
} else {
log.error('Unsupported platform & Auto-updates not yet configured for this platform.');
}

autoUpdater.setFeedURL({
provider: 'github',
owner: 'chanomhub',
repo: 'APP',
});

autoUpdater.checkForUpdatesAndNotify();
log.info('Checking for updates at:', updateURL);

app.on('activate', (): void => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});

app.on('window-all-closed', (): void => {
if (process.platform !== 'darwin') {
app.quit();
}
});

autoUpdater.on('update-available', (): void => {
BrowserWindow.getAllWindows().forEach(win => win.webContents.send('update-available'));
});

autoUpdater.on('update-downloaded', (): void => {
BrowserWindow.getAllWindows().forEach(win => win.webContents.send('update-downloaded'));
log.info('Update downloaded, quitting now...');
});
log.info('App initialization complete.');

4,001 changes: 4,001 additions & 0 deletions Desktop/package-lock.json

Large diffs are not rendered by default.

95 changes: 95 additions & 0 deletions Desktop/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"name": "Chanomhub",
"version": "0.0.7",
"description": "",
"main": "main.ts",
"scripts": {
"start": "tsc && electron ./ts-js/main.js",
"build": "electron-builder",
"build:win": "electron-builder --win",
"build:mac": "electron-builder --mac",
"build:linux": "electron-builder --linux"
},
"repository": {
"type": "git",
"url": "git+https://github.com/chanomhub/APP.git"
},
"build": {
"appId": "com.chanomhub.desktop",
"publish": [
{
"provider": "github",
"owner": "chanomhub",
"repo": "APP"
}
],
"win": {
"target": {
"target": "nsis",
"arch": [
"x64",
"ia32",
"arm64"
]
},
"icon": "chanomhub.ico",
"requestedExecutionLevel": "requireAdministrator"
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"perMachine": true,
"runAfterFinish": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true
},
"mac": {
"target": {
"target": "dmg",
"arch": [
"x64",
"arm64"
]
},
"icon": "chanomhub.icns"
},
"linux": {
"target": {
"target": "deb",
"arch": [
"x64",
"arm64",
"armv7l"
]
},
"icon": "chanomhub.png"
},
"extraMetadata": {
"win": {
"requestedExecutionLevel": "requireAdministrator"
}
},
"directories": {
"output": "dist"
}
},
"author": {
"name": "CrypticDay",
"email": "https://discord.com/invite/QTmeKmKf2w"
},
"license": "ISC",
"devDependencies": {
"@types/electron": "^1.6.10",
"@types/semver": "^7.5.8",
"electron": "^30.1.1",
"electron-builder": "^24.13.3",
"typescript": "^5.4.5"
},
"dependencies": {
"electron-dl": "^4.0.0",
"electron-log": "^5.1.5",
"electron-updater": "^6.2.1",
"i18next": "^23.11.5",
"i18next-electron-fs-backend": "^3.0.2"
}
}
31 changes: 31 additions & 0 deletions Desktop/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('electron', {
getFolders: (): Promise<string[]> => ipcRenderer.invoke('get-folders'),
openFolder: (folder: string): Promise<void> => ipcRenderer.invoke('open-folder', folder),
getDownloads: (): Promise<any[]> => ipcRenderer.invoke('get-downloads'),
pauseDownload: (id: string): Promise<void> => ipcRenderer.invoke('pause-download', id),
resumeDownload: (id: string): Promise<void> => ipcRenderer.invoke('resume-download', id),
cancelDownload: (id: string): Promise<void> => ipcRenderer.invoke('cancel-download', id),
onDownloadUpdate: (callback: (downloads: any[]) => void): void => { ipcRenderer.on('download-update', (event, downloads) => callback(downloads)); },
getDownloadPath: (): Promise<string> => ipcRenderer.invoke('get-download-path'),
setDownloadPath: (path: string): Promise<void> => ipcRenderer.invoke('set-download-path', path),

// Auto-updater events
onUpdateAvailable: (callback: () => void): void => { ipcRenderer.on('update-available', callback); },
onUpdateDownloaded: (callback: () => void): void => { ipcRenderer.on('update-downloaded', callback); }
});

window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector: string, text: string): void => {
const element = document.getElementById(selector);
if (element) element.innerText = text;
};

for (const type of ['chrome', 'node', 'electron']) {
const version = process.versions[type as keyof NodeJS.ProcessVersions];
if (version) {
replaceText(`${type}-version`, version);
}
}
});
31 changes: 31 additions & 0 deletions Desktop/renderer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// /mnt/data/renderer.ts
import { ipcRenderer } from 'electron';

ipcRenderer.on('navigate', (event, page: string) => {
switch (page) {
case 'Advanced Search':
window.location.href = 'advanced-search.html';
break;
case 'downloads':
window.location.href = 'downloads.html';
break;
case 'all-game':
window.location.href = 'all-game.html';
break;
case 'setting':
window.location.href = 'setting.html';
break;
}
});

// Auto-updater notifications
ipcRenderer.on('update-available', (): void => {
alert('A new update is available. Downloading now...');
});

ipcRenderer.on('update-downloaded', (): void => {
const userResponse = confirm('A new update is ready. Quit and install now?');
if (userResponse) {
ipcRenderer.send('install-update');
}
});
11 changes: 11 additions & 0 deletions Desktop/ts-js/advanced-search.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>

<script async src="https://cse.google.com/cse.js?cx=941ae56af19304112"></script>
<div class="gcse-searchbox-only"></div>

</body>
</html>
42 changes: 42 additions & 0 deletions Desktop/ts-js/all-game.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<title>All Game</title>
<style>
.folder-container {
display: flex;
flex-wrap: wrap;
}
.folder {
width: 20%;
margin: 1%;
padding: 10px;
border: 1px solid #000;
text-align: center;
}
.folder:hover {
cursor: pointer;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<h1>All Game</h1>
<div id="folders" class="folder-container"></div>
<script>
window.electron.getFolders().then(folders => {
const container = document.getElementById('folders');
folders.forEach(folder => {
const div = document.createElement('div');
div.className = 'folder';
div.innerText = folder;
div.onclick = () => {
window.electron.openFolder(folder);
};
container.appendChild(div);
});
});
</script>
</body>
</html>

35 changes: 35 additions & 0 deletions Desktop/ts-js/downloadManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.cancelDownload = exports.pauseDownload = exports.addDownload = exports.getDownloads = void 0;
// /mnt/data/downloadManager.ts
const path_1 = __importDefault(require("path"));
const downloads = [];
function getDownloads() {
return downloads;
}
exports.getDownloads = getDownloads;
function addDownload(filePath) {
downloads.push({
id: filePath,
name: path_1.default.basename(filePath),
status: 'completed'
});
}
exports.addDownload = addDownload;
function pauseDownload(id) {
const download = downloads.find(d => d.id === id);
if (download) {
download.status = 'paused';
}
}
exports.pauseDownload = pauseDownload;
function cancelDownload(id) {
const index = downloads.findIndex(d => d.id === id);
if (index !== -1) {
downloads.splice(index, 1);
}
}
exports.cancelDownload = cancelDownload;
106 changes: 106 additions & 0 deletions Desktop/ts-js/downloads.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html>
<head>
<title>Downloads</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
padding: 20px;
}

h1 {
color: #333;
}

.download-item {
background-color: #fff;
padding: 10px;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
display: flex;
align-items: center;
}

.download-item span {
flex-grow: 1;
font-weight: bold;
}

.download-actions button {
margin-right: 5px;
padding: 5px 10px;
border: none;
border-radius: 3px;
color: #fff;
cursor: pointer;
transition: background-color 0.3s ease;
}

.download-actions button:hover {
opacity: 0.8;
}

.download-actions button.pause {
background-color: #ffa500;
}

.download-actions button.resume {
background-color: #4caf50;
}

.download-actions button.cancel {
background-color: #f44336;
}

.progress {
width: 200px;
height: 20px;
background-color: #e0e0e0;
border-radius: 5px;
overflow: hidden;
margin-right: 10px;
}

.progress-bar {
height: 100%;
background-color: #4caf50;
width: 0%;
text-align: center;
color: white;
transition: width 0.3s ease;
}
</style>
</head>
<body>
<h1>Downloads</h1>
<div id="downloads"></div>
<script>
function updateDownloads(downloads) {
const container = document.getElementById('downloads');
container.innerHTML = ''; // Clear current list
downloads.forEach(download => {
const div = document.createElement('div');
div.className = 'download-item';
div.innerHTML = `
<span>${download.name}</span>
<div class="progress">
<div class="progress-bar" style="width: ${download.progress || 0}%">
${download.progress || 0}%
</div>
</div>
<div class="download-actions">
<button class="pause" onclick="window.electron.pauseDownload('${download.id}')">Pause</button>
<button class="resume" onclick="window.electron.resumeDownload('${download.id}')">Resume</button>
<button class="cancel" onclick="window.electron.cancelDownload('${download.id}')">Cancel</button>
</div>
`;
container.appendChild(div);
});
}
window.electron.getDownloads().then(updateDownloads);
window.electron.onDownloadUpdate(updateDownloads);
</script>
</body>
</html>
16 changes: 16 additions & 0 deletions Desktop/ts-js/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
<h1>Hello World!</h1>
<p>
We are using Node.js <span id="node-version"></span>,
Chromium <span id="chrome-version"></span>,
and Electron <span id="electron-version"></span>.
</p>
</body>
</html>
Binary file added Desktop/ts-js/loading.webp
Binary file not shown.
11 changes: 11 additions & 0 deletions Desktop/ts-js/locales/en/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"menu": {
"advancedSearch": "Advanced Search",
"downloads": "Downloads",
"profile": "Profile",
"home": "Home",
"allGame": "All Game",
"setting": "Setting"
}
}

11 changes: 11 additions & 0 deletions Desktop/ts-js/locales/th/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"menu": {
"advancedSearch": "การค้นหาขั้นสูง",
"downloads": "การดาวน์โหลด",
"profile": "โปรไฟล์",
"home": "หน้าแรก",
"allGame": "ทุกเกม",
"setting": "การตั้งค่า"
}
}

229 changes: 229 additions & 0 deletions Desktop/ts-js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const electron_1 = require("electron");
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const child_process_1 = require("child_process");
const electron_updater_1 = require("electron-updater");
const electron_log_1 = __importDefault(require("electron-log"));
const i18next_1 = __importDefault(require("i18next"));
const i18next_electron_fs_backend_1 = __importDefault(require("i18next-electron-fs-backend"));
electron_updater_1.autoUpdater.logger = electron_log_1.default;
electron_updater_1.autoUpdater.logger.transports.file.level = 'info';
electron_log_1.default.info('App starting...');
let downloadPath = electron_1.app.getPath('downloads');
let cachePath = path_1.default.join(downloadPath, 'cache');
let downloads = [];
let win; // Declare win globally
i18next_1.default.use(i18next_electron_fs_backend_1.default).init({
lng: 'en', // Default language
fallbackLng: 'en', // Fallback language
backend: {
loadPath: path_1.default.join(__dirname, 'locales/{{lng}}/translation.json'),
},
debug: true, // Set to false in production
}, (err, t) => {
if (err) {
electron_log_1.default.error('i18next initialization failed', err);
}
else {
electron_log_1.default.info('i18next initialized');
createWindow();
}
});
electron_1.app.on('ready', () => {
// Create the window once i18next is initialized
i18next_1.default.on('initialized', createWindow);
});
function createWindow() {
win = new electron_1.BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path_1.default.join(__dirname, 'preload.js'),
partition: 'persist:chanomhub',
devTools: true // Ensure developer tools are enabled
},
});
win.loadURL('https://chanomhub.xyz/');
win.webContents.openDevTools(); // Open developer tools
const menuTemplate = [
{
label: i18next_1.default.t('menu.advancedSearch'),
submenu: [
{ label: i18next_1.default.t('menu.downloads'), click: () => { win.loadFile('downloads.html'); } },
{ label: i18next_1.default.t('menu.profile'), click: () => { win.loadURL('https://chanomhub.xyz/setting/'); } },
{ label: i18next_1.default.t('menu.home'), click: () => { win.loadURL('https://chanomhub.xyz/'); } },
{ label: i18next_1.default.t('menu.allGame'), click: () => { win.loadFile('all-game.html'); } },
{ label: i18next_1.default.t('menu.setting'), click: () => { win.loadFile('setting.html'); } },
],
},
];
const menu = electron_1.Menu.buildFromTemplate(menuTemplate);
electron_1.Menu.setApplicationMenu(menu);
setupIpcHandlers();
setupDownloadHandler();
}
function setupIpcHandlers() {
electron_1.ipcMain.handle('get-folders', () => {
return fs_1.default.readdirSync(downloadPath).filter(file => fs_1.default.statSync(path_1.default.join(downloadPath, file)).isDirectory());
});
electron_1.ipcMain.handle('open-folder', (event, folder) => {
const folderPath = path_1.default.join(downloadPath, folder);
if (fs_1.default.existsSync(folderPath)) {
(0, child_process_1.exec)(`"${folderPath}"`, (error) => {
if (error) {
console.error(`Error opening folder: ${error}`);
}
});
}
});
electron_1.ipcMain.handle('get-downloads', () => {
return downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
}));
});
electron_1.ipcMain.handle('pause-download', (event, id) => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.pause();
}
electron_log_1.default.info(`Download paused: ${id}`);
});
electron_1.ipcMain.handle('resume-download', (event, id) => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.resume();
}
electron_log_1.default.info(`Download resumed: ${id}`);
});
electron_1.ipcMain.handle('cancel-download', (event, id) => {
const download = downloads.find(d => d.id === id);
if (download) {
download.item.cancel();
}
electron_log_1.default.info(`Download canceled: ${id}`);
});
electron_1.ipcMain.handle('get-download-path', () => {
electron_log_1.default.info(`Download path: ${downloadPath}`);
return downloadPath;
});
electron_1.ipcMain.handle('set-download-path', (event, newPath) => {
downloadPath = newPath;
cachePath = path_1.default.join(downloadPath, 'cache');
if (!fs_1.default.existsSync(cachePath)) {
fs_1.default.mkdirSync(cachePath);
}
electron_log_1.default.info(`Download path changed: ${downloadPath}`);
});
electron_1.ipcMain.on('install-update', () => {
electron_updater_1.autoUpdater.quitAndInstall();
});
}
function setupDownloadHandler() {
electron_1.session.defaultSession.on('will-download', (event, item) => {
const cacheFilePath = path_1.default.join(cachePath, item.getFilename());
if (fs_1.default.existsSync(cacheFilePath)) {
electron_log_1.default.info(`File already in cache: ${item.getFilename()}`);
win.webContents.send('download-complete', {
id: item.getURL(),
name: item.getFilename(),
path: cacheFilePath,
});
return;
}
item.setSavePath(cacheFilePath);
electron_log_1.default.info(`Download started: ${item.getFilename()}`);
const download = {
id: item.getURL(),
name: item.getFilename(),
item,
progress: 0,
};
downloads.push(download);
item.on('done', (event, state) => {
if (state === 'completed') {
electron_log_1.default.info(`Download completed: ${item.getFilename()}`);
}
else {
electron_log_1.default.error(`Download failed: ${state}`, item.getFilename());
}
downloads = downloads.filter(d => d.id !== item.getURL());
win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
});
item.on('updated', (event, state) => {
if (state === 'interrupted') {
electron_log_1.default.info(`Download paused: ${item.getFilename()}`);
}
else if (state === 'progressing') {
if (item.isPaused()) {
electron_log_1.default.info(`Download paused: ${item.getFilename()}`);
}
else {
const progress = Math.round((item.getReceivedBytes() / item.getTotalBytes()) * 100);
download.progress = progress;
win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
}
}
});
win.webContents.send('download-update', downloads.map(download => ({
id: download.id,
name: download.name,
progress: download.progress,
})));
});
}
electron_1.app.whenReady().then(() => {
createWindow();
let updateURL = `${electron_1.app.getAppPath()}/releases/latest`;
if (process.platform === 'win32') {
updateURL += `/download/${electron_1.app.getVersion()}/${electron_1.app.getName()}-Setup-${electron_1.app.getVersion()}.exe`;
}
else if (process.platform === 'darwin') {
updateURL += `/download/${electron_1.app.getVersion()}/${electron_1.app.getName()}-${electron_1.app.getVersion()}-${process.arch}.dmg`;
}
else if (process.platform === 'linux') {
updateURL += `/download/${electron_1.app.getVersion()}/${electron_1.app.getName()}-${electron_1.app.getVersion()}-${process.arch}.deb`;
}
else {
electron_log_1.default.error('Unsupported platform & Auto-updates not yet configured for this platform.');
}
electron_updater_1.autoUpdater.setFeedURL({
provider: 'github',
owner: 'chanomhub',
repo: 'APP',
});
electron_updater_1.autoUpdater.checkForUpdatesAndNotify();
electron_log_1.default.info('Checking for updates at:', updateURL);
electron_1.app.on('activate', () => {
if (electron_1.BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
electron_1.app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
electron_1.app.quit();
}
});
electron_updater_1.autoUpdater.on('update-available', () => {
electron_1.BrowserWindow.getAllWindows().forEach(win => win.webContents.send('update-available'));
});
electron_updater_1.autoUpdater.on('update-downloaded', () => {
electron_1.BrowserWindow.getAllWindows().forEach(win => win.webContents.send('update-downloaded'));
electron_log_1.default.info('Update downloaded, quitting now...');
});
electron_log_1.default.info('App initialization complete.');
30 changes: 30 additions & 0 deletions Desktop/ts-js/preload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const electron_1 = require("electron");
electron_1.contextBridge.exposeInMainWorld('electron', {
getFolders: () => electron_1.ipcRenderer.invoke('get-folders'),
openFolder: (folder) => electron_1.ipcRenderer.invoke('open-folder', folder),
getDownloads: () => electron_1.ipcRenderer.invoke('get-downloads'),
pauseDownload: (id) => electron_1.ipcRenderer.invoke('pause-download', id),
resumeDownload: (id) => electron_1.ipcRenderer.invoke('resume-download', id),
cancelDownload: (id) => electron_1.ipcRenderer.invoke('cancel-download', id),
onDownloadUpdate: (callback) => { electron_1.ipcRenderer.on('download-update', (event, downloads) => callback(downloads)); },
getDownloadPath: () => electron_1.ipcRenderer.invoke('get-download-path'),
setDownloadPath: (path) => electron_1.ipcRenderer.invoke('set-download-path', path),
// Auto-updater events
onUpdateAvailable: (callback) => { electron_1.ipcRenderer.on('update-available', callback); },
onUpdateDownloaded: (callback) => { electron_1.ipcRenderer.on('update-downloaded', callback); }
});
window.addEventListener('DOMContentLoaded', () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector);
if (element)
element.innerText = text;
};
for (const type of ['chrome', 'node', 'electron']) {
const version = process.versions[type];
if (version) {
replaceText(`${type}-version`, version);
}
}
});
30 changes: 30 additions & 0 deletions Desktop/ts-js/renderer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// /mnt/data/renderer.ts
const electron_1 = require("electron");
electron_1.ipcRenderer.on('navigate', (event, page) => {
switch (page) {
case 'Advanced Search':
window.location.href = 'advanced-search.html';
break;
case 'downloads':
window.location.href = 'downloads.html';
break;
case 'all-game':
window.location.href = 'all-game.html';
break;
case 'setting':
window.location.href = 'setting.html';
break;
}
});
// Auto-updater notifications
electron_1.ipcRenderer.on('update-available', () => {
alert('A new update is available. Downloading now...');
});
electron_1.ipcRenderer.on('update-downloaded', () => {
const userResponse = confirm('A new update is ready. Quit and install now?');
if (userResponse) {
electron_1.ipcRenderer.send('install-update');
}
});
75 changes: 75 additions & 0 deletions Desktop/ts-js/setting.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!DOCTYPE html>
<html>
<head>
<title>Setting</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 50px;
}
h1 {
color: #333;
}
form {
display: flex;
flex-direction: column;
width: 300px;
}
label, input, button {
margin-bottom: 10px;
}
input[type="text"] {
padding: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 7px 10px;
border: none;
background-color: #4CAF50;
color: white;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<h1>Setting</h1>
<form id="settings-form">
<label for="download-path">Download Path:</label>
<input type="text" id="download-path" name="download-path" required>
<input type="button" id="browse" value="Browse">
<button type="submit">Save</button>
</form>

<script>
// Get the download path from Electron
window.electron.getDownloadPath().then(path => {
document.getElementById('download-path').value = path;
});

// Handle form submission
document.getElementById('settings-form').addEventListener('submit', (event) => {
event.preventDefault();
const path = document.getElementById('download-path').value;
window.electron.setDownloadPath(path);
});

// Handle Browse button click
document.getElementById('browse').addEventListener('click', () => {
window.electron.showOpenDialog({
properties: ['openDirectory']
}).then(result => {
if (!result.canceled) {
document.getElementById('download-path').value = result.filePaths[0];
}
}).catch(err => {
console.error(err);
});
});
</script>
</body>
</html>
12 changes: 12 additions & 0 deletions Desktop/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "ts-js",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["*.ts"]
}
2,056 changes: 2,056 additions & 0 deletions Desktop/yarn.lock

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions scr/Mobile/MenuOptions.dart → Mobile/MenuOptions.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
enum MenuOptions {
showUserAgent,
listCookies,
clearCookies,
addToCache,
listCache,
clearCache,
navigationDelegate,
doPostRequest,
loadLocalFile,
loadFlutterAsset,
loadHtmlString,
transparentBackground,
setCookie,
logExample,
basicAuthentication,
downloadFile,
deleteDownloadedFile,
setCustomDownloadDirectory,
enum MenuOptions {
showUserAgent,
listCookies,
clearCookies,
addToCache,
listCache,
clearCache,
navigationDelegate,
doPostRequest,
loadLocalFile,
loadFlutterAsset,
loadHtmlString,
transparentBackground,
setCookie,
logExample,
basicAuthentication,
downloadFile,
deleteDownloadedFile,
setCustomDownloadDirectory,
}
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';


class NavigationControls extends StatelessWidget {
const NavigationControls({super.key, required this.webViewController});

final WebViewController webViewController;

@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () async {
if (await webViewController.canGoBack()) {
await webViewController.goBack();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No back history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () async {
if (await webViewController.canGoForward()) {
await webViewController.goForward();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No forward history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: () => webViewController.reload(),
),
],
);
}

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';


class NavigationControls extends StatelessWidget {
const NavigationControls({super.key, required this.webViewController});

final WebViewController webViewController;

@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
IconButton(
icon: const Icon(Icons.arrow_back_ios),
onPressed: () async {
if (await webViewController.canGoBack()) {
await webViewController.goBack();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No back history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.arrow_forward_ios),
onPressed: () async {
if (await webViewController.canGoForward()) {
await webViewController.goForward();
} else {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No forward history item')),
);
}
}
},
),
IconButton(
icon: const Icon(Icons.replay),
onPressed: () => webViewController.reload(),
),
],
);
}
}
1,354 changes: 677 additions & 677 deletions scr/Mobile/main.dart → Mobile/main.dart

Large diffs are not rendered by default.