Skip to content

Commit

Permalink
Use vuex, save and load from localstorage, improve UI, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
LouWii committed Sep 5, 2021
1 parent dd3f5a7 commit 2f91ca0
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 102 deletions.
8 changes: 8 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"bootstrap": "^3.4.1",
"electron-updater": "4.5.1",
"vue": "3.2.6",
"vue-router": "4.0.11"
"vue-router": "4.0.11",
"vuex": "^4.0.2"
}
}
1 change: 0 additions & 1 deletion packages/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="script-src 'self' blob:">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css" />
<title>Hosts File Edit</title>
</head>
<body>
Expand Down
100 changes: 18 additions & 82 deletions packages/renderer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,29 @@
<div class="actions-container">
<button
class="btn btn-default"
title="Add new line"
@click="addHost"
>
Add
<span class="glyphicon glyphicon-plus" />
</button>
<button
class="btn btn-primary btn-save-hosts"
title="Save to hosts file"
:disabled="saveIntoFileButtonDisabled"
:class="saveIntoFileButtonClass"
@click="saveHostsFile"
>
<span class="glyphicon glyphicon-floppy-disk" />
</button>
<div class="btn-group">
<button
class="btn btn-primary btn-save-hosts"
:disabled="saveIntoFileButtonDisabled"
:class="saveIntoFileButtonClass"
@click="saveHostsFile"
>
<span class="glyphicon" />
<span class="text-state text">Save to <em>hosts</em> file</span>
<span class="text-state text-saving">Saving...</span>
<span class="text-state text-saved">Saved !</span>
<span class="text-state text-error">Error</span>
</button>
<button
type="button"
class="btn btn-primary dropdown-toggle"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<span class="caret" />
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li>
<a
href="#"
@click="importHostsList"
>Import settings</a>
</li>
<li>
<a
href="#"
@click="exportHostsList"
>Export settings</a>
</li>
</ul>
</div>
</div>
<main>
<hosts-list :hosts="hosts" />
<hosts-list />
</main>
</template>

<script lang="ts">
import type { Host } from 'types';
import {defineComponent} from 'vue';
import HostsList from '/@/components/HostsList.vue';
import {getHosts} from '/@/hosts-helper';
export default defineComponent({
name: 'App',
Expand All @@ -63,13 +33,12 @@ export default defineComponent({
},
data() {
return {
hosts: getHosts() as Array<Host>,
savingIntoFile: false,
savingIntoFileState: 0,
};
},
computed: {
saveIntoFileButtonClass(): Record<string, unknown> {
saveIntoFileButtonClass(): Record<string, boolean> {
return {
saving: this.savingIntoFile,
saved: this.savingIntoFileState == 1,
Expand All @@ -82,7 +51,7 @@ export default defineComponent({
},
methods: {
addHost() {
this.hosts.push({str: '', active: true, index: this.hosts.length + 1});
this.$store.commit('addNewHost')
},
saveHostsFile() {
let mm = 'tt';
Expand Down Expand Up @@ -126,22 +95,15 @@ body {
z-index: 10;
}
.actions-container button {
margin-left: 1rem;
}
main {
overflow: auto;
padding: 2rem;
}
.btn-save-hosts .text-saving, .btn-save-hosts .text-saved, .btn-save-hosts .text-error {
display: none;
}
.btn-save-hosts .glyphicon::before {
content: "\e202";
}
.btn-save-hosts.saving:hover {
background: #337ab7;
}
.btn-save-hosts.saving .glyphicon {
animation-name: spin;
animation-duration: 2000ms;
Expand All @@ -151,32 +113,6 @@ main {
.btn-save-hosts.saving .glyphicon::before {
content: "\e019";
}
.btn-save-hosts.saving .text, .btn-save-hosts.saving .text-saved {
display: none;
}
.btn-save-hosts.saving .text-saving {
display: inline;
}
.btn-save-hosts.saved .glyphicon::before {
content: "\e013";
}
.btn-save-hosts.saved .text {
display: none;
}
.btn-save-hosts.saved .text-saved {
display: inline;
}
.btn-save-hosts.error .glyphicon::before {
content: "\e101";
}
.btn-save-hosts.error .text {
display: none;
}
.btn-save-hosts.error .text-error {
display: inline;
}
@keyframes spin {
from {transform:rotate(0deg);}
Expand Down
21 changes: 17 additions & 4 deletions packages/renderer/src/components/HostItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
v-model="localHostStr"
class="form-control"
type="text"
@change="updateHostStr"
>
<span class="input-group-btn">
<button
type="button"
class="btn"
:class="{'btn-success': host.active, 'btn-default': !host.active}"
:title="host.active ? 'Active' : 'Inactive'"
@click="activateHost"
@click="activateHostToggle"
>
<span
class="glyphicon"
Expand Down Expand Up @@ -48,19 +49,31 @@ export default defineComponent({
data() {
return {
localHostStr: '',
updateDebounce: null as unknown as NodeJS.Timeout,
};
},
beforeMount(): void {
this.localHostStr = this.host.str;
},
methods: {
activateHost() {
this.$emit('activate-host' );
activateHostToggle() {
this.$store.commit('toggleHostActive', this.host.index);
},
removeHost() {
this.$emit('remove-host' );
this.$store.commit('removeHost', this.host.index);
},
updateHostStr() {
this.$store.commit('updateHostStr', {index: this.host.index, str: this.localHostStr});
},
},
watch: {
localHostStr() {
clearTimeout(this.updateDebounce);
this.updateDebounce = setTimeout(() => {
this.$store.commit('updateHostStr', {index: this.host.index, str: this.localHostStr});
}, 200);
}
}
});
</script>

Expand Down
14 changes: 3 additions & 11 deletions packages/renderer/src/components/HostsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,17 @@
</template>

<script lang="ts">
import type { Host } from 'types';
import type { PropType} from 'vue';
import {defineComponent} from 'vue';
import { mapState } from 'vuex';
import HostItem from '/@/components/HostItem.vue';
export default defineComponent({
name: 'HostsList',
components: {
HostItem,
},
props: {
hosts: {
required: true,
type: Array as PropType<Array<Host>>,
},
},
setup() {
return {};
computed: {
...mapState(['hosts']),
},
methods: {
Expand Down
File renamed without changes.
6 changes: 4 additions & 2 deletions packages/renderer/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {createApp} from 'vue';
import App from '/@/App.vue';
import store from '/@/store';
import 'bootstrap/dist/css/bootstrap.min.css';

createApp(App)
.mount('#app');
const app = createApp(App);
app.use(store);
app.mount('#app');
20 changes: 20 additions & 0 deletions packages/renderer/src/storage-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Host } from "types";

const saveKey = 'hosts_list';

export const saveHosts = function(hosts: Array<Host>): void {
if (localStorage) {
localStorage.setItem(saveKey, JSON.stringify(hosts));
}
}

export const loadHosts = function(): Array<Host> {
if (localStorage) {
const jsonHosts = localStorage.getItem(saveKey);
if (jsonHosts) {
const hosts: Array<Host> = JSON.parse(jsonHosts);
return hosts;
}
}
return [];
}
54 changes: 54 additions & 0 deletions packages/renderer/src/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Host } from 'types';
import { HostStrUpdate, State } from 'types/vuex';
import { createStore, Store } from 'vuex';
import { loadHosts, saveHosts } from './storage-helper';

const saveToStoragePlugin = (store: Store<State>) => {
store.subscribe((mutation, state) => {
saveHosts(state.hosts);
})
};

export default createStore({
state(): State {
// TODO: Combine hosts from hosts file and from local storage
const loadedHosts: Array<Host> = loadHosts();

return {
hosts: loadedHosts,
}
},
plugins: [saveToStoragePlugin],
mutations: {
addNewHost(state: State) {
let maxIndex = 0;
state.hosts.forEach(host => {
if (host.index > maxIndex) maxIndex = host.index;
});
const host: Host = {
str: '127.0.0.1 site.local',
active: true,
index: maxIndex + 1
};
state.hosts.push(host);
},
removeHost(state: State, index: number) {
const i = state.hosts.findIndex(host => host.index === index);
if (typeof i !== 'undefined') {
state.hosts.splice(i, 1);
}
},
toggleHostActive(state: State, index: number) {
const host = state.hosts.find(h => h.index === index);
if (typeof host !== 'undefined') {
Object.assign(host, {active: !host.active});
}
},
updateHostStr(state: State, payload: HostStrUpdate) {
const host = state.hosts.find(h => h.index === payload.index);
if (typeof host !== 'undefined') {
Object.assign(host, {str: payload.str});
}
},
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export interface Host {
str: string,
active: boolean,
index: number,
}
}

17 changes: 17 additions & 0 deletions packages/renderer/types/vuex.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'

export interface State {
hosts: Array<Host>
}

export interface HostStrUpdate {
index: number,
str: string,
}

declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: Store<State>
}
}

0 comments on commit 2f91ca0

Please sign in to comment.