Skip to content

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
Epxir committed Aug 27, 2023
0 parents commit 527f022
Show file tree
Hide file tree
Showing 31 changed files with 1,184 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
dist-electron
release
*.local

# Editor directories and files
.vscode/.debug.env
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# lockfile
package-lock.json
pnpm-lock.yaml
yarn.lock
80 changes: 80 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
English | [简体中文](README_zh-CN.md)

<h1 align="center">
<br>
<img src="public/chameleon.ico" width="150"/></a>
<br>
Chameleon
<br>
</h1>
<h4 align="center">Automatically and customizably update your desktop wallpaper from API sources or Bing Wallpaper</h4>

![Static Badge](https://img.shields.io/badge/build-passing-Chartreuse)

![Alt text](chameleon.gif)

## :sparkles: Features
**:computer: Supported platforms**

- Window :ballot_box_with_check:
MacOS :black_medium_square:
Linux :black_medium_square:

**:robot: Update modes**

- Interval fixed time
- selected multiple moments
- Folder :information_source:

**:framed_picture: Wallpaper sources**
* Bing Wallpaper

:ballot_box_with_check:Get watermark-free Bing wallpapers

:ballot_box_with_check:Browse recent wallpapers

* API interface

:ballot_box_with_check:Get and download from any API

:black_medium_square:Save specified number

* Interact with other software :jigsaw:

:black_medium_square:Wallpaper Engine( creating a folder:trollface: )

## :unicorn: Usage
Chameleon is simple and pure, no need for complicated setup, just download the corresponding platfor


## :gear: Build

You need `node.js` and other environments before building by yourself.

#### Clone code

```shell
git clone --recurse-submodules https://github.com/cloudreve/Cloudreve.git
```

#### Install dependency modules

```shell
npm install && npm run dev
```



#### Compile project

```shell
npm run build
```

## :alembic: Technology stack

* [Electron](https://www.electronjs.org/) + [Vite](https://vitejs.dev/) + [Vue3](https://vuejs.org/) + [TypeScript](https://www.typescriptlang.org/) + [element plus](https://element-plus.org/)

## :scroll: License

MIT
81 changes: 81 additions & 0 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
[English](README.md) | 简体中文

<h1 align="center">
<br>
<img src="public/chameleon.ico" width="150"/></a>
<br>
Chameleon
<br>
</h1>
<h4 align="center">自动化,可定制地从API接口或必应壁纸源更新桌面背景</h4>

![Static Badge](https://img.shields.io/badge/build-passing-Chartreuse)

![Alt text](chameleon.gif)

## :sparkles: 特性
**:computer: 支持平台**

- Window :ballot_box_with_check:
MacOS :black_medium_square:
Linux :black_medium_square:

**:robot: 更新方式**

- 间隔固定时间
- 选定多个时刻
- 文件夹 :information_source:

**:framed_picture: 壁纸来源**
* Bing Wallpaper

:ballot_box_with_check:获取无水印必应壁纸

:ballot_box_with_check:浏览近期壁纸

* API接口

:ballot_box_with_check:从任意API中获取并下载

:black_medium_square:保存指定数量

* 与其他软件交互 :jigsaw:

:black_medium_square:Wallpaper Engine( 新建文件夹:trollface: )

## :unicorn: 使用
Chameleon 既简洁又纯粹,无需复杂的设置,下载对应平台即可


## :gear: 构建

自行构建前需要 `node.js` 等环境。

#### 克隆代码

```shell
git clone --recurse-submodules https://github.com/Epxir/Chameleon.git
```

#### 安装依赖模块

```shell
npm install && npm run dev
```



#### 编译项目

```shell
npm run build
```

## :alembic: 技术栈

* [Electron](https://www.electronjs.org/) + [Vite](https://vitejs.dev/) + [Vue3](https://vuejs.org/) + [TypeScript](https://www.typescriptlang.org/) + [element plus](https://element-plus.org/)


## :scroll: 许可证

MIT
Binary file added chameleon.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions electron-builder.json5
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @see https://www.electron.build/configuration/configuration
*/
{
"$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/master/packages/app-builder-lib/scheme.json",
"appId": "com.epxir.chameleon",
"asar": true,
"directories": {
"output": "release/${version}"
},
"files": [
"dist-electron",
"dist"
],
"mac": {
"icon": "public/chameleon.ico",
"artifactName": "${productName}_${version}.${ext}",
"target": [
"dmg"
]
},
"win": {
"icon": "public/chameleon.ico",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
],
"artifactName": "${productName}_${version}.${ext}"
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"deleteAppDataOnUninstall": false
}
}
22 changes: 22 additions & 0 deletions electron/electron-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/// <reference types="vite-plugin-electron/electron-env" />

declare namespace NodeJS {
interface ProcessEnv {
/**
* The built directory structure
*
* ```tree
* ├─┬─┬ dist
* │ │ └── index.html
* │ │
* │ ├─┬ dist-electron
* │ │ ├── main.js
* │ │ └── preload.js
* │
* ```
*/
DIST: string
/** /dist/ or /public/ */
PUBLIC: string
}
}
122 changes: 122 additions & 0 deletions electron/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { app, BrowserWindow, shell, dialog, ipcMain, Tray, Menu, nativeImage } from 'electron'
import path from 'node:path'
import electronDl from 'electron-dl'

// The built directory structure
//
// ├─┬─┬ dist
// │ │ └── index.html
// │ │
// │ ├─┬ dist-electron
// │ │ ├── main.js
// │ │ └── preload.js
// │
process.env.DIST = path.join(__dirname, '../dist')
process.env.PUBLIC = app.isPackaged ? process.env.DIST : path.join(process.env.DIST, '../public')


let win: BrowserWindow | null

const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']

function createWindow() {
win = new BrowserWindow({
frame: false,
height:585,
width:1040,
icon: path.join(process.env.PUBLIC, 'electron.png'),
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: true,
contextIsolation: false,
webSecurity: false,
},

})

win.webContents.on('did-finish-load', () => {
win?.webContents.send('main-process-message', (new Date).toLocaleString())
})

if (VITE_DEV_SERVER_URL) {
win.loadURL(VITE_DEV_SERVER_URL)
} else {
win.loadFile(path.join(process.env.DIST, 'index.html'))
}
win.webContents.setWindowOpenHandler(({ url }) => {
if (url.startsWith('https:')) shell.openExternal(url)
return { action: 'deny' }
})
}

const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', () => {
if (win) {
if (win.isMinimized()) win.restore()
if (win.isVisible()) {
win.focus()
} else {
win.show()
}
}
})
app.whenReady().then(() => {
const tray = new Tray(nativeImage.createFromPath(path.join(process.env.DIST,'electron.png')))
const contextMenu = Menu.buildFromTemplate([
{label:'Quit',click:()=>{app.quit()}}
])
tray.setContextMenu(contextMenu)
tray.setToolTip('electron')
tray.on('click', () => {win!.show()})
createWindow()
if (process.argv.indexOf("--Hidden") >= 0)
win!.hide();
})
}



ipcMain.on('window', (_:Event,event:string) => {
if (event=="min") {win!.minimize();}
if (event=="close") {win!.hide()}
})

ipcMain.handle('bootup', (_:Event,event?:boolean) => {
if (event != undefined) {
app.setLoginItemSettings({
openAtLogin: event,
args: ["--Hidden"],
})
return
}
else {
const { openAtLogin } = app.getLoginItemSettings({
args: ["--Hidden"],
});
return openAtLogin;
}
})


ipcMain.handle("getpath", async (_:Event,path?) =>{
return path == undefined ? app.getPath("userData") : app.getPath(path)
})

ipcMain.handle("choosefolder", async() =>{
const win = BrowserWindow.getFocusedWindow()!;
const folder = await dialog.showOpenDialog(win,{properties:['openDirectory']});
if (folder.canceled) {
return
} else {
return folder.filePaths[0]
}
})

ipcMain.handle("download", async (_:Event,url:string,path:string) =>{
path = path == "" ? app.getPath("downloads") : path
const dl = await electronDl.download(win!,url,{directory:path});
return dl.getSavePath()
})
Loading

0 comments on commit 527f022

Please sign in to comment.