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

* upstream/develop: (60 commits)
  whoops
  whoops
  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
  remove deploy stage
  remove deploy stage
  updated and completed German translation
  On logout switch to public timeline.
  minor modification of Chinese translation
  update Chinese translation
  Add Chinese language
  Fix posting.
  Put oauth text into description.
  Display OAuth login on login form button.
  ...
This commit is contained in:
Henry Jameson 2018-11-26 05:21:58 +03:00
commit a806d43f05
56 changed files with 2963 additions and 383 deletions

View file

@ -15,6 +15,7 @@ const STATUS_URL = '/api/statuses/show'
const MEDIA_UPLOAD_URL = '/api/statusnet/media/upload'
const CONVERSATION_URL = '/api/statusnet/conversation'
const MENTIONS_URL = '/api/statuses/mentions.json'
const DM_TIMELINE_URL = '/api/statuses/dm_timeline.json'
const FOLLOWERS_URL = '/api/statuses/followers.json'
const FRIENDS_URL = '/api/statuses/friends.json'
const FOLLOWING_URL = '/api/friendships/create.json'
@ -52,16 +53,6 @@ let fetch = (url, options) => {
return oldfetch(fullUrl, options)
}
// from https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
let utoa = (str) => {
// first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str)
.replace(/%([0-9A-F]{2})/g,
(match, p1) => { return String.fromCharCode('0x' + p1) }))
}
// Params
// cropH
// cropW
@ -175,9 +166,9 @@ const register = (params) => {
})
}
const authHeaders = (user) => {
if (user && user.username && user.password) {
return { 'Authorization': `Basic ${utoa(`${user.username}:${user.password}`)}` }
const authHeaders = (accessToken) => {
if (accessToken) {
return { 'Authorization': `Bearer ${accessToken}` }
} else {
return { }
}
@ -302,6 +293,7 @@ const fetchTimeline = ({timeline, credentials, since = false, until = false, use
public: PUBLIC_TIMELINE_URL,
friends: FRIENDS_TIMELINE_URL,
mentions: MENTIONS_URL,
dms: DM_TIMELINE_URL,
notifications: QVITTER_USER_NOTIFICATIONS_URL,
'publicAndExternal': PUBLIC_AND_EXTERNAL_TIMELINE_URL,
user: QVITTER_USER_TIMELINE_URL,

View file

@ -0,0 +1,82 @@
import {reduce} from 'lodash'
const getOrCreateApp = ({oauth, instance}) => {
const url = `${instance}/api/v1/apps`
const form = new window.FormData()
form.append('client_name', `PleromaFE_${Math.random()}`)
form.append('redirect_uris', `${window.location.origin}/oauth-callback`)
form.append('scopes', 'read write follow')
return window.fetch(url, {
method: 'POST',
body: form
}).then((data) => data.json())
}
const login = (args) => {
getOrCreateApp(args).then((app) => {
args.commit('setClientData', app)
const data = {
response_type: 'code',
client_id: app.client_id,
redirect_uri: app.redirect_uri,
scope: 'read write follow'
}
const dataString = reduce(data, (acc, v, k) => {
const encoded = `${k}=${encodeURIComponent(v)}`
if (!acc) {
return encoded
} else {
return `${acc}&${encoded}`
}
}, false)
// Do the redirect...
const url = `${args.instance}/oauth/authorize?${dataString}`
window.location.href = url
})
}
const getTokenWithCredentials = ({app, instance, username, password}) => {
const url = `${instance}/oauth/token`
const form = new window.FormData()
form.append('client_id', app.client_id)
form.append('client_secret', app.client_secret)
form.append('grant_type', 'password')
form.append('username', username)
form.append('password', password)
return window.fetch(url, {
method: 'POST',
body: form
}).then((data) => data.json())
}
const getToken = ({app, instance, code}) => {
const url = `${instance}/oauth/token`
const form = new window.FormData()
form.append('client_id', app.client_id)
form.append('client_secret', app.client_secret)
form.append('grant_type', 'authorization_code')
form.append('code', code)
form.append('redirect_uri', `${window.location.origin}/oauth-callback`)
return window.fetch(url, {
method: 'POST',
body: form
}).then((data) => data.json())
}
const oauth = {
login,
getToken,
getTokenWithCredentials,
getOrCreateApp
}
export default oauth

View file

@ -0,0 +1,16 @@
import utils from './utils.js'
const search = ({query, store}) => {
return utils.request({
store,
url: '/api/pleroma/search_user',
params: {
query
}
}).then((data) => data.json())
}
const UserSearch = {
search
}
export default UserSearch

View file

@ -0,0 +1,36 @@
const queryParams = (params) => {
return Object.keys(params)
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
.join('&')
}
const headers = (store) => {
const accessToken = store.state.oauth.token
if (accessToken) {
return {'Authorization': `Bearer ${accessToken}`}
} else {
return {}
}
}
const request = ({method = 'GET', url, params, store}) => {
const instance = store.state.instance.server
let fullUrl = `${instance}${url}`
if (method === 'GET' && params) {
fullUrl = fullUrl + `?${queryParams(params)}`
}
return window.fetch(fullUrl, {
method,
headers: headers(store),
credentials: 'same-origin'
})
}
const utils = {
queryParams,
request
}
export default utils