Merge remote-tracking branch 'upstream/develop' into feature/scope_preferences

* upstream/develop:
  DM timeline: stream new statuses
  update-japanese-translation
  Add actual user search.
  incorporate most translation changes from MR 368
  update french translation
  Always show dm panel.
  Add direct message tab.
  api service url
  On logout switch to public timeline.
  Put oauth text into description.
  Display OAuth login on login form button.
  Add login form back in.
  Linting.
  Re-activate registration, use oauth password flow to fetch token.
  Fix typo.
  Remove gonsole.logg :DD
  Fix linting.
  Move login to oauth.
This commit is contained in:
Henry Jameson 2018-11-26 04:38:44 +03:00
commit e06717fd0d
32 changed files with 1576 additions and 279 deletions

View file

@ -0,0 +1,14 @@
import Timeline from '../timeline/timeline.vue'
const DMs = {
computed: {
timeline () {
return this.$store.state.statuses.timelines.dms
}
},
components: {
Timeline
}
}
export default DMs

View file

@ -0,0 +1,5 @@
<template>
<Timeline :title="$t('nav.dms')" v-bind:timeline="timeline" v-bind:timeline-name="'dms'"/>
</template>
<script src="./dm_timeline.js"></script>

View file

@ -1,22 +1,40 @@
import oauthApi from '../../services/new_api/oauth.js'
const LoginForm = {
data: () => ({
user: {},
authError: false
}),
computed: {
loginMethod () { return this.$store.state.instance.loginMethod },
loggingIn () { return this.$store.state.users.loggingIn },
registrationOpen () { return this.$store.state.instance.registrationOpen }
},
methods: {
oAuthLogin () {
oauthApi.login({
oauth: this.$store.state.oauth,
instance: this.$store.state.instance.server,
commit: this.$store.commit
})
},
submit () {
this.$store.dispatch('loginUser', this.user).then(
() => {},
(error) => {
this.authError = error
this.user.username = ''
this.user.password = ''
}
)
const data = {
oauth: this.$store.state.oauth,
instance: this.$store.state.instance.server
}
oauthApi.getOrCreateApp(data).then((app) => {
oauthApi.getTokenWithCredentials(
{
app,
instance: data.instance,
username: this.user.username,
password: this.user.password})
.then((result) => {
this.$store.commit('setToken', result.access_token)
this.$store.dispatch('loginUser', result.access_token)
this.$router.push('/main/friends')
})
})
}
}
}

View file

@ -5,7 +5,7 @@
{{$t('login.login')}}
</div>
<div class="panel-body">
<form v-on:submit.prevent='submit(user)' class='login-form'>
<form v-if="loginMethod == 'password'" v-on:submit.prevent='submit(user)' class='login-form'>
<div class='form-group'>
<label for='username'>{{$t('login.username')}}</label>
<input :disabled="loggingIn" v-model='user.username' class='form-control' id='username' v-bind:placeholder="$t('login.placeholder')">
@ -20,8 +20,17 @@
<button :disabled="loggingIn" type='submit' class='btn btn-default'>{{$t('login.login')}}</button>
</div>
</div>
<div v-if="authError" class='form-group'>
<div class='alert error'>{{authError}}</div>
</form>
<form v-if="loginMethod == 'token'" v-on:submit.prevent='oAuthLogin' class="login-form">
<div class="form-group">
<p>{{$t('login.description')}}</p>
</div>
<div class='form-group'>
<div class='login-bottom'>
<div><router-link :to="{name: 'registration'}" v-if='registrationOpen' class='register'>{{$t('login.register')}}</router-link></div>
<button :disabled="loggingIn" type='submit' class='btn btn-default'>{{$t('login.login')}}</button>
</div>
</div>
</form>
</div>

View file

@ -12,6 +12,11 @@
{{ $t("nav.mentions") }}
</router-link>
</li>
<li v-if='currentUser'>
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
{{ $t("nav.dms") }}
</router-link>
</li>
<li v-if='currentUser && currentUser.locked'>
<router-link to='/friend-requests'>
{{ $t("nav.friend_requests") }}

View file

@ -0,0 +1,20 @@
import oauth from '../../services/new_api/oauth.js'
const oac = {
props: ['code'],
mounted () {
if (this.code) {
oauth.getToken({
app: this.$store.state.oauth,
instance: this.$store.state.instance.server,
code: this.code
}).then((result) => {
this.$store.commit('setToken', result.access_token)
this.$store.dispatch('loginUser', result.access_token)
this.$router.push('/main/friends')
})
}
}
}
export default oac

View file

@ -0,0 +1,5 @@
<template>
<h1>...</h1>
</template>
<script src="./oauth_callback.js"></script>

View file

@ -1,3 +1,5 @@
import oauthApi from '../../services/new_api/oauth.js'
const registration = {
data: () => ({
user: {},
@ -25,9 +27,23 @@ const registration = {
this.$store.state.api.backendInteractor.register(this.user).then(
(response) => {
if (response.ok) {
this.$store.dispatch('loginUser', this.user)
this.$router.push('/main/all')
this.registering = false
const data = {
oauth: this.$store.state.oauth,
instance: this.$store.state.instance.server
}
oauthApi.getOrCreateApp(data).then((app) => {
oauthApi.getTokenWithCredentials(
{
app,
instance: data.instance,
username: this.user.username,
password: this.user.password})
.then((result) => {
this.$store.commit('setToken', result.access_token)
this.$store.dispatch('loginUser', result.access_token)
this.$router.push('/main/friends')
})
})
} else {
this.registering = false
response.json().then((data) => {

View file

@ -7,25 +7,10 @@ const UserFinder = {
}),
methods: {
findUser (username) {
username = username[0] === '@' ? username.slice(1) : username
this.loading = true
this.$store.state.api.backendInteractor.externalProfile(username)
.then((user) => {
this.loading = false
this.hidden = true
if (!user.error) {
this.$store.commit('addNewUsers', [user])
this.$router.push({name: 'user-profile', params: {id: user.id}})
} else {
this.error = true
}
})
this.$router.push({ name: 'user-search', query: { query: username } })
},
toggleHidden () {
this.hidden = !this.hidden
},
dismissError () {
this.error = false
}
}
}

View file

@ -1,9 +1,5 @@
<template>
<span class="user-finder-container">
<span class="alert error" v-if="error">
<i class="icon-cancel user-finder-icon" @click="dismissError"/>
{{$t('finder.error_fetching_user')}}
</span>
<i class="icon-spin4 user-finder-icon animate-spin-slow" v-if="loading" />
<a href="#" v-if="hidden"><i class="icon-user-plus user-finder-icon" @click.prevent.stop="toggleHidden"/></a>
<span v-else>

View file

@ -0,0 +1,33 @@
import UserCard from '../user_card/user_card.vue'
import userSearchApi from '../../services/new_api/user_search.js'
const userSearch = {
components: {
UserCard
},
props: [
'query'
],
data () {
return {
users: []
}
},
mounted () {
this.search(this.query)
},
watch: {
query (newV) {
this.search(newV)
}
},
methods: {
search (query) {
userSearchApi.search({query, store: this.$store})
.then((res) => {
this.users = res
})
}
}
}
export default userSearch

View file

@ -0,0 +1,12 @@
<template>
<div class="user-seach panel panel-default">
<div class="panel-heading">
{{$t('nav.user_search')}}
</div>
<div class="panel-body">
<user-card v-for="user in users" :key="user.id" :user="user" :showFollows="true"></user-card>
</div>
</div>
</template>
<script src="./user_search.js"></script>