Skip to content

Commit b8e7fd0

Browse files
committed
Remove calls to set loading user
1 parent 001bce6 commit b8e7fd0

9 files changed

Lines changed: 183 additions & 107 deletions

File tree

web/components/MessageThreadHeader.vue

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
<p class="text--secondary mb-n1">
2323
{{ $store.getters.getOwner | phoneCountry }}
2424
</p>
25-
<v-tooltip v-if="$store.getters.getHeartbeat" right>
25+
<v-tooltip v-if="$store.getters.getHeartbeat" right open-on-click>
2626
<template #activator="{ on, attrs }">
2727
<v-btn
2828
x-small
2929
v-bind="attrs"
3030
color="success"
3131
class="ml-2 mt-1 mb-n1"
3232
icon
33+
@click.prevent
3334
v-on="on"
3435
>
3536
<v-icon x-small>mdi-circle</v-icon>
@@ -41,20 +42,57 @@
4142
</div>
4243
</div>
4344
<v-spacer></v-spacer>
44-
<v-tooltip bottom :open-on-click="true">
45-
<template #activator="{ on, attrs }">
46-
<v-btn icon text v-bind="attrs" v-on="on" @click.prevent>
45+
<v-menu offset-y>
46+
<template #activator="{ on }">
47+
<v-btn icon text v-on="on">
4748
<v-icon>mdi-dots-vertical</v-icon>
4849
</v-btn>
4950
</template>
50-
<span>More Options</span>
51-
</v-tooltip>
51+
<v-list class="px-2" nav :dense="$vuetify.breakpoint.mdAndDown">
52+
<v-list-item-group>
53+
<v-list-item :to="{ name: 'index' }">
54+
<v-list-item-icon class="pl-2">
55+
<v-icon dense>mdi-account-cog</v-icon>
56+
</v-list-item-icon>
57+
<v-list-item-content class="ml-n3">
58+
<v-list-item-title class="pr-16 py-1">
59+
<span :class="{ 'pr-16': $vuetify.breakpoint.mdAndUp }">
60+
Settings
61+
</span>
62+
</v-list-item-title>
63+
</v-list-item-content>
64+
</v-list-item>
65+
<v-list-item @click.prevent="logout">
66+
<v-list-item-icon class="pl-2">
67+
<v-icon dense>mdi-logout</v-icon>
68+
</v-list-item-icon>
69+
<v-list-item-content class="ml-n3">
70+
<v-list-item-title class="pr-16 py-1">
71+
<span :class="{ 'pr-16': $vuetify.breakpoint.mdAndUp }">
72+
Logout
73+
</span>
74+
</v-list-item-title>
75+
</v-list-item-content>
76+
</v-list-item>
77+
</v-list-item-group>
78+
</v-list>
79+
</v-menu>
5280
</v-sheet>
5381
</template>
5482

5583
<script lang="ts">
5684
import { Vue, Component } from 'vue-property-decorator'
5785
5886
@Component
59-
export default class MessageThreadHeader extends Vue {}
87+
export default class MessageThreadHeader extends Vue {
88+
logout(): void {
89+
this.$fire.auth.signOut().then(() => {
90+
this.$store.dispatch('addNotification', {
91+
type: 'info',
92+
message: 'You have successfully logged out',
93+
})
94+
this.$router.push({ name: 'login' })
95+
})
96+
}
97+
}
6098
</script>

web/layouts/default.vue

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ export default class DefaultLayout extends Vue {
3535
}
3636
3737
mounted() {
38-
Promise.all([
39-
this.$store.dispatch('loadThreads'),
40-
this.$store.dispatch('getHeartbeat'),
41-
])
4238
this.startPoller()
4339
}
4440

web/middleware/auth.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Context, Middleware } from '@nuxt/types'
2+
3+
const authMiddleware: Middleware = (context: Context) => {
4+
if (context.store.getters.getUser === null) {
5+
context.redirect('/login')
6+
}
7+
}
8+
9+
export default authMiddleware

web/middleware/user.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import { User as StateUser } from '~/store'
44
import { setAuthHeader } from '~/plugins/axios'
55

66
export default async function (context: Context) {
7-
await context.store.dispatch('setLoadingUser', true)
87
await setUser(context)
9-
await context.store.dispatch('setLoadingUser', false)
108
}
119

1210
const setUser = (context: Context): Promise<User | null> => {

web/pages/index.vue

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,32 @@
11
<template>
2-
<v-row v-if="$vuetify.breakpoint.lgAndUp" align="center" justify="center">
3-
<div>
4-
<v-img
5-
class="mx-auto mb-4"
6-
max-height="400"
7-
max-width="90%"
8-
contain
9-
:src="require('~/assets/img/person-texting.svg')"
10-
></v-img>
11-
<div class="text-center">
12-
<h3 class="text-h5 mt-4">Select a thread</h3>
13-
<p class="text--secondary">Send and receive messages using our API</p>
14-
</div>
15-
</div>
16-
</v-row>
17-
<v-row v-else justify="end">
18-
<v-col class="px-0 py-0">
19-
<message-thread-header></message-thread-header>
20-
<message-thread></message-thread>
21-
</v-col>
22-
</v-row>
2+
<v-container fill-height fluid>
3+
<v-row align="center" justify="center">
4+
<v-col
5+
cols="12"
6+
md="4"
7+
xl="3"
8+
:class="{ 'mt-n16': $vuetify.breakpoint.lgAndUp }"
9+
>
10+
<h3 class="text-h2 text-center mb-4">Login</h3>
11+
<v-card max-width="360" class="mx-auto">
12+
<v-card-text class="px-0">
13+
<no-ssr>
14+
<firebase-auth></firebase-auth>
15+
</no-ssr>
16+
</v-card-text>
17+
</v-card>
18+
<div class="text-center mt-4">
19+
<back-button></back-button>
20+
</div>
21+
</v-col>
22+
</v-row>
23+
</v-container>
2324
</template>
2425

25-
<script>
26-
export default {
27-
name: 'IndexPage',
28-
}
26+
<script lang="ts">
27+
import Vue from 'vue'
28+
import { Component } from 'vue-property-decorator'
29+
30+
@Component
31+
export default class Index extends Vue {}
2932
</script>

web/pages/login.vue

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,5 @@ import Vue from 'vue'
2828
import { Component } from 'vue-property-decorator'
2929
3030
@Component
31-
export default class Login extends Vue {
32-
layout: string = 'auth'
33-
}
31+
export default class Login extends Vue {}
3432
</script>

web/pages/threads/_id.vue

Lines changed: 67 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -123,72 +123,82 @@
123123
</template>
124124

125125
<script lang="ts">
126-
import { Vue, Component } from 'vue-property-decorator'
126+
import Vue from 'vue'
127127
import { InputValidationRules } from 'vuetify'
128128
import { Message } from '~/models/message'
129129
import { SendMessageRequest } from '~/store'
130130
131-
@Component
132-
export default class ThreadsIndex extends Vue {
133-
formMessage = ''
134-
formMessageRules: InputValidationRules = [
135-
(v) => !!v || 'Message is required',
136-
(v) => (v && v.length <= 320) || 'Message must be less than 320 characters',
137-
]
131+
export default Vue.extend({
132+
middleware: ['auth'],
133+
data() {
134+
const formMessageRules: InputValidationRules = [
135+
(v) => !!v || 'Message is required',
136+
(v) =>
137+
(v && v.length <= 320) || 'Message must be less than 320 characters',
138+
]
139+
return {
140+
formMessage: '',
141+
formMessageRules,
142+
submitting: false,
143+
}
144+
},
138145
139-
submitting = false
146+
computed: {
147+
messages(): Array<Message> {
148+
return [...this.$store.getters.getThreadMessages].reverse()
149+
},
150+
},
140151
141-
async mounted(): Promise<void> {
152+
async mounted() {
142153
await this.$store.dispatch('loadThreads')
143154
await this.$store.dispatch('loadThreadMessages', this.$route.params.id)
144155
this.scrollToElement()
145-
}
146-
147-
get messages(): Array<Message> {
148-
return [...this.$store.getters.getThreadMessages].reverse()
149-
}
150-
151-
isPending(message: Message): boolean {
152-
return ['sending', 'pending'].includes(message.status)
153-
}
154-
155-
isMT(message: Message): boolean {
156-
return message.type === 'mobile-terminated'
157-
}
158-
159-
scrollToElement() {
160-
const el: Element = this.$refs.messageBody as Element
161-
el.scrollTop = el.scrollHeight + 120
162-
}
163-
164-
async sendMessage(event: KeyboardEvent) {
165-
if (event.shiftKey) {
166-
return
167-
}
168-
169-
if (!(this.$refs.form as any).validate()) {
170-
return
171-
}
172-
173-
this.submitting = true
174-
const request: SendMessageRequest = {
175-
from: this.$store.getters.getOwner,
176-
to: this.$store.getters.getThread.contact,
177-
content: this.formMessage,
178-
}
179-
180-
await this.$store.dispatch('sendMessage', request)
181-
182-
this.formMessage = ''
183-
this.submitting = false
184-
185-
this.$nextTick(() => {
186-
;(this.$refs.messageInput as any).$refs.input.focus()
187-
this.scrollToElement()
188-
;(this.$refs.form as any).reset()
189-
})
190-
}
191-
}
156+
},
157+
158+
methods: {
159+
isPending(message: Message): boolean {
160+
return ['sending', 'pending'].includes(message.status)
161+
},
162+
163+
isMT(message: Message): boolean {
164+
return message.type === 'mobile-terminated'
165+
},
166+
167+
scrollToElement() {
168+
const el: Element = this.$refs.messageBody as Element
169+
el.scrollTop = el.scrollHeight + 120
170+
},
171+
172+
async sendMessage(event: KeyboardEvent) {
173+
if (event.shiftKey) {
174+
return
175+
}
176+
177+
if (!(this.$refs.form as any).validate()) {
178+
return
179+
}
180+
181+
this.submitting = true
182+
183+
const request: SendMessageRequest = {
184+
from: this.$store.getters.getOwner,
185+
to: this.$store.getters.getThread.contact,
186+
content: this.formMessage,
187+
}
188+
189+
await this.$store.dispatch('sendMessage', request)
190+
191+
this.formMessage = ''
192+
this.submitting = false
193+
194+
this.$nextTick(() => {
195+
;(this.$refs.messageInput as any).$refs.input.focus()
196+
this.scrollToElement()
197+
;(this.$refs.form as any).reset()
198+
})
199+
},
200+
},
201+
})
192202
</script>
193203

194204
<style lang="scss">

web/pages/threads/index.vue

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<template>
2+
<v-row v-if="$vuetify.breakpoint.lgAndUp" align="center" justify="center">
3+
<div>
4+
<v-img
5+
class="mx-auto mb-4"
6+
max-height="400"
7+
max-width="90%"
8+
contain
9+
:src="require('assets/img/person-texting.svg')"
10+
></v-img>
11+
<div class="text-center">
12+
<h3 class="text-h5 mt-4">Select a thread</h3>
13+
<p class="text--secondary">Send and receive messages using our API</p>
14+
</div>
15+
</div>
16+
</v-row>
17+
<v-row v-else justify="end">
18+
<v-col class="px-0 py-0">
19+
<message-thread-header></message-thread-header>
20+
<message-thread></message-thread>
21+
</v-col>
22+
</v-row>
23+
</template>
24+
25+
<script>
26+
export default {
27+
name: 'IndexPage',
28+
}
29+
</script>

web/store/index.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export type User = {
2727
export type State = {
2828
owner: string
2929
user: User | null
30-
loadingUser: boolean
3130
threads: Array<MessageThread>
3231
threadId: string | null
3332
heartbeat: null | Heartbeat
@@ -50,7 +49,6 @@ export const state = (): State => ({
5049
type: 'success',
5150
timeout: defaultNotificationTimeout,
5251
},
53-
loadingUser: false,
5452
})
5553

5654
export type AppData = {
@@ -74,6 +72,10 @@ export const getters = {
7472
}
7573
},
7674

75+
getUser(state: State): User | null {
76+
return state.user
77+
},
78+
7779
getOwner(state: State): string {
7880
return state.owner
7981
},
@@ -123,9 +125,6 @@ export const mutations = {
123125
setPooling(state: State, payload: boolean) {
124126
state.pooling = payload
125127
},
126-
setLoadingUser(state: State, payload: boolean) {
127-
state.loadingUser = payload
128-
},
129128
setUser(state: State, payload: User | null) {
130129
state.user = payload
131130
},
@@ -219,10 +218,6 @@ export const actions = {
219218
context.commit('setThreadMessages', response.data.data)
220219
},
221220

222-
async setLoadingUser(context: ActionContext<State, State>, loading: boolean) {
223-
await context.commit('setLoadingUser', loading)
224-
},
225-
226221
setUser(context: ActionContext<State, State>, user: User | null) {
227222
context.commit('setUser', user)
228223
},

0 commit comments

Comments
 (0)