diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/imap.js | 34 | ||||
-rw-r--r-- | app/index.html | 13 | ||||
-rw-r--r-- | app/main.js | 39 | ||||
-rw-r--r-- | app/src/App.vue | 3 | ||||
-rw-r--r-- | app/src/components/Folders.vue | 21 | ||||
-rw-r--r-- | app/src/components/Panel.vue | 34 | ||||
-rw-r--r-- | app/src/index.js | 13 | ||||
-rw-r--r-- | app/src/mixins/dynamicModelObjectEmit.js | 16 | ||||
-rw-r--r-- | app/src/pages/Home.vue | 99 | ||||
-rw-r--r-- | app/src/router.js | 12 | ||||
-rw-r--r-- | app/src/store.js | 30 |
11 files changed, 314 insertions, 0 deletions
diff --git a/app/imap.js b/app/imap.js new file mode 100644 index 0000000..1ac76a4 --- /dev/null +++ b/app/imap.js @@ -0,0 +1,34 @@ +const { ipcMain } = require('electron'); +const { ImapFlow } = require('imapflow'); + +ipcMain.on('imap:listTree:from', listTreeFrom); +ipcMain.on('imap:listTree:to', listTreeTo); + +async function connect (options) { + const client = new ImapFlow({ + host: options.server, + port: options.port, + auth: { + user: options.username, + pass: options.password, + }, + }); + + await client.connect(); + + return client; +} + +async function listTreeFrom (event, options) { + const client = await connect(options); + + event.reply('imap:listTree:from:reply', await client.listTree()); + await client.logout(); +} + +async function listTreeTo (event, options) { + const client = await connect(options); + + event.reply('imap:listTree:to:reply', await client.listTree()); + await client.logout(); +} diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..8b7ddc9 --- /dev/null +++ b/app/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="UTF-8"> + <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> + <title>Hello World!</title> + <link rel="stylesheet" href="./build/index.css"> +</head> +<body> +<div id="app"></div> +<script src="./build/index.js"></script> +</body> +</html> diff --git a/app/main.js b/app/main.js new file mode 100644 index 0000000..c2b8e30 --- /dev/null +++ b/app/main.js @@ -0,0 +1,39 @@ +const { app, BrowserWindow } = require('electron'); +// const path = require('path'); +const isProduction = process.env.NODE_ENV === 'production'; + +require('./imap'); + +function createWindow () { + const mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + // preload: path.join(__dirname, 'preload.js') + nodeIntegration: true, + contextIsolation: false, + }, + }); + + mainWindow.loadFile('index.html'); + + if (!isProduction) { + mainWindow.webContents.openDevTools(); + } +} + +app.whenReady().then(() => { + createWindow(); + + app.on('activate', function () { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } + }); +}); + +app.on('window-all-closed', function () { + if (process.platform !== 'darwin') { + app.quit(); + } +}); diff --git a/app/src/App.vue b/app/src/App.vue new file mode 100644 index 0000000..98240ae --- /dev/null +++ b/app/src/App.vue @@ -0,0 +1,3 @@ +<template> + <router-view /> +</template> diff --git a/app/src/components/Folders.vue b/app/src/components/Folders.vue new file mode 100644 index 0000000..b801c1a --- /dev/null +++ b/app/src/components/Folders.vue @@ -0,0 +1,21 @@ +<template> + <li> + <div> + {{ folder.root ? '' : folder.name }} + </div> + <ul v-if="folder.folders"> + <Folders v-for="(child, idx) in folder.folders" :key="idx" :folder="child" /> + </ul> + </li> +</template> + +<script> +export default { + props: { + folder: { + type: Object, + required: true, + }, + }, +}; +</script> diff --git a/app/src/components/Panel.vue b/app/src/components/Panel.vue new file mode 100644 index 0000000..3ae4000 --- /dev/null +++ b/app/src/components/Panel.vue @@ -0,0 +1,34 @@ +<template> + <div class="panel"> + <label> + Server <input type="text" :value="modelValue.server" @input="emit('server', $event.target.value)"> + </label> + <label> + Port <input type="text" :value="modelValue.port" @input="emit('port', $event.target.value)"> + </label> + <label> + Username <input type="text" :value="modelValue.username" @input="emit('username', $event.target.value)"> + </label> + <label> + Passwort <input type="text" :value="modelValue.password" @input="emit('password', $event.target.value)"> + </label> + <button @click="$emit('connect')"> + Connect + </button> + </div> +</template> + +<script> +import dynamicModelObjectEmit from '../mixins/dynamicModelObjectEmit'; + +export default { + mixins: [ + dynamicModelObjectEmit, + ], + + emits: ['connect'], +}; +</script> + +<style lang="scss"> +</style> diff --git a/app/src/index.js b/app/src/index.js new file mode 100644 index 0000000..46dc556 --- /dev/null +++ b/app/src/index.js @@ -0,0 +1,13 @@ +import { createApp } from 'vue'; +import router from './router'; +import store from './store'; +import App from './App'; + +const app = createApp(App); + +app.config.globalProperties.$electron = require('electron'); + +app.use(router); +app.use(store); + +app.mount('#app'); diff --git a/app/src/mixins/dynamicModelObjectEmit.js b/app/src/mixins/dynamicModelObjectEmit.js new file mode 100644 index 0000000..93701c8 --- /dev/null +++ b/app/src/mixins/dynamicModelObjectEmit.js @@ -0,0 +1,16 @@ +export default { + props: { + modelValue: { + type: Object, + required: true, + }, + }, + + emits: ['update:modelValue'], + + methods: { + emit (key, value) { + this.$emit('update:modelValue', { ...this.modelValue, [key]: value }); + }, + }, +}; diff --git a/app/src/pages/Home.vue b/app/src/pages/Home.vue new file mode 100644 index 0000000..2fe4030 --- /dev/null +++ b/app/src/pages/Home.vue @@ -0,0 +1,99 @@ +<template> + <div class="wrap"> + <div class="panels"> + <Panel v-model="from" @connect="connectFrom" /> + <Panel v-model="to" @connect="connectTo" /> + </div> + <button @click="migrate"> + Migrate! + </button> + + <h1>FROM</h1> + <ul v-if="from.folders"> + <Folders :folder="from.folders" /> + </ul> + <code> + {{ from.folders }} + </code> + + <h1>TO</h1> + <ul v-if="to.folders"> + <Folders :folder="to.folders" /> + </ul> + <code> + {{ to.folders }} + </code> + </div> +</template> + +<script> +import Panel from '../components/Panel.vue'; +import Folders from '../components/Folders'; + +export default { + components: { + Panel, + Folders, + }, + + data () { + return {}; + }, + + computed: { + from: { + set (value) { + this.$store.commit('setFrom', value); + }, + get () { + return this.$store.state.from; + }, + }, + to: { + set (value) { + this.$store.commit('setTo', value); + }, + get () { + return this.$store.state.to; + }, + }, + }, + + mounted () { + this.$electron.ipcRenderer.on('imap:listTree:from:reply', (event, folders) => { + this.from.folders = folders; + }); + + this.$electron.ipcRenderer.on('imap:listTree:to:reply', (event, folders) => { + this.to.folders = folders; + }); + }, + + methods: { + connectFrom () { + this.$electron.ipcRenderer.send('imap:listTree:from', JSON.parse(JSON.stringify(this.from))); + }, + + connectTo () { + this.$electron.ipcRenderer.send('imap:listTree:to', JSON.parse(JSON.stringify(this.to))); + }, + + async migrate () { + + }, + }, +}; +</script> + +<style lang="scss"> +body { + margin: 0; + font-size: 1rem; + font-family: Helvetica, sans-serif; +} + +.panels { + display: flex; + justify-content: space-between; +} +</style> diff --git a/app/src/router.js b/app/src/router.js new file mode 100644 index 0000000..7676449 --- /dev/null +++ b/app/src/router.js @@ -0,0 +1,12 @@ +import { createRouter, createWebHashHistory } from 'vue-router'; +import Home from './pages/Home'; + +export default createRouter({ + history: createWebHashHistory(), + routes: [ + { + path: '/', + component: Home, + }, + ], +}); diff --git a/app/src/store.js b/app/src/store.js new file mode 100644 index 0000000..db5a9fa --- /dev/null +++ b/app/src/store.js @@ -0,0 +1,30 @@ +import { createStore } from 'vuex'; + +export default createStore({ + state () { + return { + from: { + server: 'localhost', + port: '3143', + username: 'd@cool.de', + password: 'lolo11', + }, + to: { + server: '', + port: '', + username: '', + password: '', + }, + }; + }, + + mutations: { + setFrom (state, payload) { + state.from = Object.assign(state.from, payload); + }, + + setTo (state, payload) { + state.to = Object.assign(state.to, payload); + }, + }, +}); |