Merge pull request #17 from h3poteto/iss-3
closes #3 Fix login page design
This commit is contained in:
commit
1ea2497c2c
|
@ -5,15 +5,12 @@ export default class Account {
|
|||
this.db = db
|
||||
}
|
||||
|
||||
listInstances () {
|
||||
listAccounts () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.find({accessToken: { $ne: '' }}, (err, doc) => {
|
||||
this.db.find({accessToken: { $ne: '' }}, (err, docs) => {
|
||||
if (err) return reject(err)
|
||||
if (empty(doc)) return reject(new EmptyRecordError('empty'))
|
||||
const instances = doc.map((e, i, array) => {
|
||||
return { baseURL: e.baseURL, id: e._id }
|
||||
})
|
||||
resolve(instances)
|
||||
if (empty(docs)) return reject(new EmptyRecordError('empty'))
|
||||
resolve(docs)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -29,7 +26,7 @@ export default class Account {
|
|||
if (empty(doc)) return reject(new EmptyRecordError('empty'))
|
||||
const instance = {
|
||||
baseURL: doc.baseURL,
|
||||
id: doc.id
|
||||
id: doc._id
|
||||
}
|
||||
resolve(instance)
|
||||
}
|
||||
|
|
|
@ -102,15 +102,15 @@ ipcMain.on('get-social-token', (event, _) => {
|
|||
})
|
||||
|
||||
// nedb
|
||||
ipcMain.on('list-instances', (event, _) => {
|
||||
ipcMain.on('list-accounts', (event, _) => {
|
||||
const account = new Account(db)
|
||||
account.listInstances()
|
||||
account.listAccounts()
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
event.sender.send('error-list-instances', err)
|
||||
event.sender.send('error-list-accounts', err)
|
||||
})
|
||||
.then((instances) => {
|
||||
event.sender.send('response-list-instances', instances)
|
||||
.then((accounts) => {
|
||||
event.sender.send('response-list-accounts', accounts)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div id="authorize">
|
||||
<el-form ref="form" :model="authorizeForm" label-width="120px" label-position="top">
|
||||
<el-form ref="form" :model="authorizeForm" label-width="120px" label-position="top" class="authorize-form">
|
||||
<el-form-item label="Please paste authorization code from your browser:">
|
||||
<el-input v-model="authorizeForm.code"></el-input>
|
||||
</el-form-item>
|
||||
|
@ -35,7 +35,29 @@ export default {
|
|||
<style lang="scss">
|
||||
body { font-family: 'Source Sans Pro', sans-serif; }
|
||||
|
||||
html, body, #app, #authorize {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#authorize {
|
||||
background-color: #292f3f;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
|
||||
.authorize-form {
|
||||
width: 500px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #ffffff;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -2,17 +2,17 @@
|
|||
<div id="global_header">
|
||||
<el-menu
|
||||
:default-active="defaultActive"
|
||||
class="el-menu-vertical instance-menu"
|
||||
@open="instanceSelected"
|
||||
@close="instanceClosed"
|
||||
class="el-menu-vertical account-menu"
|
||||
@open="accountSelected"
|
||||
@close="accountClosed"
|
||||
:collapse="isCollapse"
|
||||
:route="true"
|
||||
background-color="#4a5664"
|
||||
text-color="#909399"
|
||||
active-text-color="#ffffff">
|
||||
<el-menu-item :index="index.toString()" v-for="(instance, index) in instances" v-bind:key="instance.id" :route="{path: `/${instance.id}/home`}">
|
||||
<el-menu-item :index="index.toString()" v-for="(account, index) in accounts" v-bind:key="account.id" :route="{path: `/${account.id}/home`}">
|
||||
<i class="el-icon-menu"></i>
|
||||
<span slot="title">{{ instance.baseURL }}</span>
|
||||
<span slot="title">{{ account.baseURL }}</span>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
<div class="space">
|
||||
|
@ -34,23 +34,23 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
instances: state => state.GlobalHeader.instances
|
||||
accounts: state => state.GlobalHeader.accounts
|
||||
})
|
||||
},
|
||||
created () {
|
||||
this.$store.dispatch('GlobalHeader/listInstances')
|
||||
.then((instances) => {
|
||||
return this.$router.push({ path: `/${instances[0].id}/home` })
|
||||
this.$store.dispatch('GlobalHeader/listAccounts')
|
||||
.then((accounts) => {
|
||||
return this.$router.push({ path: `/${accounts[0]._id}/home` })
|
||||
})
|
||||
.catch(() => {
|
||||
return this.$router.push({ path: '/login' })
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
instanceSelected (key, keyPath) {
|
||||
accountSelected (key, keyPath) {
|
||||
console.log(key, keyPath)
|
||||
},
|
||||
instanceClosed (key, keyPath) {
|
||||
accountClosed (key, keyPath) {
|
||||
console.log(key, keyPath)
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ html, body, #app, #global_header {
|
|||
}
|
||||
|
||||
#global_header {
|
||||
.instance-menu {
|
||||
.account-menu {
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
|
|
|
@ -1,74 +1,47 @@
|
|||
<template>
|
||||
<div id="login">
|
||||
<el-form ref="instanceForm" label-width="120px" label-position="top">
|
||||
<el-form-item label="Domain name">
|
||||
<el-input v-model="instanceForm.domain"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit">
|
||||
<el-button type="primary" @click="search">Search</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-form ref="loginForm" v-if="instances.length > 0" label-width="120px" label-position="top">
|
||||
<el-form-item label="Select instance">
|
||||
<el-radio-group v-model="loginForm.selectInstance" @change="changeInstance">
|
||||
<el-radio class="instance-list" v-for="instance in instances" v-bind:key="instance.id" :label="instance.name" border></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit">
|
||||
<el-button type="primary" @click="login" v-if="selectedInstance !== null">Login</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<instance-form v-if="page == 1"></instance-form>
|
||||
<login-form v-if="page == 2"></login-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import InstanceForm from './Login/InstanceForm'
|
||||
import LoginForm from './Login/LoginForm'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'login',
|
||||
data () {
|
||||
return {
|
||||
instanceForm: {
|
||||
domain: ''
|
||||
},
|
||||
loginForm: {
|
||||
selectInstance: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
instances: state => state.Login.instances,
|
||||
selectedInstance: state => state.Login.selectedInstance
|
||||
page: state => state.Login.page
|
||||
})
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
login () {
|
||||
this.$store.dispatch('Login/fetchLogin', this.selectedInstance)
|
||||
.then((url) => {
|
||||
this.$router.push({ path: '/authorize' })
|
||||
})
|
||||
},
|
||||
search () {
|
||||
this.$store.dispatch('Login/searchInstance', this.instanceForm.domain)
|
||||
},
|
||||
changeInstance (value) {
|
||||
this.$store.dispatch('Login/changeInstance', value)
|
||||
}
|
||||
}
|
||||
components: { InstanceForm, LoginForm }
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
body { font-family: 'Source Sans Pro', sans-serif; }
|
||||
|
||||
html, body, #app, #login {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#login {
|
||||
background-color: #292f3f;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
|
||||
.instance-list {
|
||||
display: block;
|
||||
.el-form-item__label {
|
||||
color: #f0f3f9;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
background-color: #373d48;
|
||||
color: #ffffff;
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div id="instance_form">
|
||||
<el-form ref="instanceForm" label-width="120px" label-position="top" class="instance-form">
|
||||
<el-form-item label="Domain name">
|
||||
<el-input v-model="instanceForm.domain" class="input"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item class="submit">
|
||||
<el-button type="primary" @click="search">Search</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'instance-form',
|
||||
data () {
|
||||
return {
|
||||
instanceForm: {
|
||||
domain: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
search () {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: 'Loading',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
this.$store.dispatch('Login/searchInstance', this.instanceForm.domain)
|
||||
.then(() => {
|
||||
loading.close()
|
||||
this.$store.commit('Login/changePage', 2)
|
||||
})
|
||||
.catch(() => {
|
||||
this.$message({
|
||||
message: 'Could not search instance',
|
||||
type: 'error'
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.instance-form {
|
||||
width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,72 @@
|
|||
<template>
|
||||
<div id="login_form">
|
||||
<el-form ref="loginForm" label-width="120px" label-position="top">
|
||||
<el-form-item label="Select instance">
|
||||
<el-radio-group v-model="loginForm.selectInstance" @change="changeInstance" class="instance-group">
|
||||
<el-radio class="instance-list" v-for="instance in instances" v-bind:key="instance.id" :label="instance.name" border></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<p v-if="instances.length === 0">Could not find instance</p>
|
||||
<el-form-item class="submit">
|
||||
<el-button type="text" class="back" @click="back"><icon name="chevron-left"></icon></el-button>
|
||||
<el-button type="primary" class="login" @click="login" v-if="selectedInstance !== null">Login</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'login-form',
|
||||
data () {
|
||||
return {
|
||||
loginForm: {
|
||||
selectInstance: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
instances: state => state.Login.instances,
|
||||
selectedInstance: state => state.Login.selectedInstance
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
login () {
|
||||
this.$store.dispatch('Login/fetchLogin', this.selectedInstance)
|
||||
.then((url) => {
|
||||
this.$router.push({ path: '/authorize' })
|
||||
})
|
||||
},
|
||||
changeInstance (value) {
|
||||
this.$store.dispatch('Login/changeInstance', value)
|
||||
},
|
||||
back () {
|
||||
this.$store.dispatch('Login/pageBack')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.instance-group {
|
||||
width: 300px;
|
||||
text-align: left;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.instance-list {
|
||||
display: block;
|
||||
width: 300px;
|
||||
margin-left: 0 !important;
|
||||
border-color: #606266;
|
||||
color: #dcdfe6;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.back {
|
||||
margin-right: 20px;
|
||||
}
|
||||
</style>
|
|
@ -8,11 +8,11 @@ const Authorize = {
|
|||
submit ({ commit }, code) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-access-token', code)
|
||||
ipcRenderer.on('response-get-access-token', (event, id) => {
|
||||
ipcRenderer.once('response-get-access-token', (event, id) => {
|
||||
console.log(id)
|
||||
resolve(id)
|
||||
})
|
||||
ipcRenderer.on('error-get-access-token', (event, err) => {
|
||||
ipcRenderer.once('error-get-access-token', (event, err) => {
|
||||
console.log(err)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -3,23 +3,24 @@ import { ipcRenderer } from 'electron'
|
|||
const GlobalHeader = {
|
||||
namespaced: true,
|
||||
state: {
|
||||
instances: []
|
||||
accounts: []
|
||||
},
|
||||
mutations: {
|
||||
updateInstances (state, instances) {
|
||||
state.instances = instances
|
||||
updateAccounts (state, accounts) {
|
||||
state.accounts = accounts
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
listInstances ({ commit }) {
|
||||
listAccounts ({ commit }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('list-instances', 'list')
|
||||
ipcRenderer.on('error-list-instances', (event, err) => {
|
||||
ipcRenderer.send('list-accounts', 'list')
|
||||
ipcRenderer.once('error-list-accounts', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.on('response-list-instances', (event, instances) => {
|
||||
commit('updateInstances', instances)
|
||||
resolve(instances)
|
||||
ipcRenderer.once('response-list-accounts', (event, accounts) => {
|
||||
commit('updateAccounts', accounts)
|
||||
console.log(accounts)
|
||||
resolve(accounts)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -5,43 +5,58 @@ const Login = {
|
|||
namespaced: true,
|
||||
state: {
|
||||
instances: [],
|
||||
selectedInstance: null
|
||||
selectedInstance: null,
|
||||
page: 1
|
||||
},
|
||||
mutations: {
|
||||
updateInstances (state, body) {
|
||||
state.instances = body.instances
|
||||
updateInstances (state, instances) {
|
||||
state.instances = instances
|
||||
},
|
||||
changeInstance (state, instance) {
|
||||
state.selectedInstance = instance
|
||||
},
|
||||
changePage (state, page) {
|
||||
state.page = page
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
searchInstance ({ commit }, domain) {
|
||||
ipcRenderer.send('get-social-token', 'get')
|
||||
ipcRenderer.on('response-get-social-token', (event, token) => {
|
||||
axios
|
||||
.get(`https://instances.social/api/1.0/instances/search?q=${domain}`, {
|
||||
'headers': { 'Authorization': `Bearer ${token}` }
|
||||
})
|
||||
.then((res) => {
|
||||
commit('updateInstances', res.data)
|
||||
console.log(res.data)
|
||||
})
|
||||
console.log(domain)
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-social-token', 'get')
|
||||
ipcRenderer.once('error-get-social-token', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.once('response-get-social-token', (event, token) => {
|
||||
axios
|
||||
.get(`https://instances.social/api/1.0/instances/search?q=${domain}`, {
|
||||
'headers': { 'Authorization': `Bearer ${token}` }
|
||||
})
|
||||
.then((res) => {
|
||||
commit('updateInstances', res.data.instances)
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
fetchLogin ({ commit }, instance) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-auth-url', instance)
|
||||
ipcRenderer.on('error-get-auth-url', (event, err) => {
|
||||
ipcRenderer.once('error-get-auth-url', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.on('response-get-auth-url', (event, url) => {
|
||||
ipcRenderer.once('response-get-auth-url', (event, url) => {
|
||||
resolve(url)
|
||||
})
|
||||
})
|
||||
},
|
||||
changeInstance ({ commit }, instance) {
|
||||
commit('changeInstance', instance)
|
||||
},
|
||||
pageBack ({ commit }) {
|
||||
commit('changePage', 1)
|
||||
commit('updateInstances', [])
|
||||
commit('changeInstance', null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,21 @@ const SideMenu = {
|
|||
actions: {
|
||||
fetchInstance ({ commit }, id) {
|
||||
ipcRenderer.send('get-instance', id)
|
||||
ipcRenderer.on('error-get-instance', (event, err) => {
|
||||
ipcRenderer.once('error-get-instance', (event, err) => {
|
||||
// TODO: handle error
|
||||
console.log(err)
|
||||
})
|
||||
ipcRenderer.on('response-get-instance', (event, instance) => {
|
||||
ipcRenderer.once('response-get-instance', (event, instance) => {
|
||||
commit('updateInstance', instance)
|
||||
})
|
||||
},
|
||||
username ({ commit }, id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.send('get-local-account', id)
|
||||
ipcRenderer.on('error-get-local-account', (event, err) => {
|
||||
ipcRenderer.once('error-get-local-account', (event, err) => {
|
||||
reject(err)
|
||||
})
|
||||
ipcRenderer.on('response-get-local-account', (event, account) => {
|
||||
ipcRenderer.once('response-get-local-account', (event, account) => {
|
||||
const client = new Mastodon(
|
||||
{
|
||||
access_token: account.accessToken,
|
||||
|
|
Loading…
Reference in New Issue