summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2021-06-22 00:18:35 +0200
committerDaniel Weipert <code@drogueronin.de>2021-06-22 00:18:35 +0200
commitf6096a18016be63c719d2ce5a27d64363862b0fd (patch)
treefae30d63ff1ad2903236cab86d61cc4978f3dfe9 /app
Initial commit
Diffstat (limited to 'app')
-rw-r--r--app/imap.js34
-rw-r--r--app/index.html13
-rw-r--r--app/main.js39
-rw-r--r--app/src/App.vue3
-rw-r--r--app/src/components/Folders.vue21
-rw-r--r--app/src/components/Panel.vue34
-rw-r--r--app/src/index.js13
-rw-r--r--app/src/mixins/dynamicModelObjectEmit.js16
-rw-r--r--app/src/pages/Home.vue99
-rw-r--r--app/src/router.js12
-rw-r--r--app/src/store.js30
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);
+ },
+ },
+});