forked from cybrespace/pinafore
		
	start on themes
This commit is contained in:
		
							parent
							
								
									fb9bc18edf
								
							
						
					
					
						commit
						eaaacdeef5
					
				
					 15 changed files with 222 additions and 97 deletions
				
			
		
							
								
								
									
										8
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							| 
						 | 
				
			
			@ -2881,10 +2881,10 @@
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "idb-keyval": {
 | 
			
		||||
      "version": "2.3.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/idb-keyval/-/idb-keyval-2.3.0.tgz",
 | 
			
		||||
      "integrity": "sha1-TURLgMP4b8vNUTIbTcvJJHxZSMA="
 | 
			
		||||
    "idb": {
 | 
			
		||||
      "version": "2.0.4",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/idb/-/idb-2.0.4.tgz",
 | 
			
		||||
      "integrity": "sha512-Nw4ykKrrVje6YODRiRm/k2ucFEQeoY+zrkszfOuzVmxx8yyBMtZh2KLaRCKk9r5GzhuF0QlNCVjBewP2n5OZ7Q=="
 | 
			
		||||
    },
 | 
			
		||||
    "ieee754": {
 | 
			
		||||
      "version": "1.1.8",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
    "extract-text-webpack-plugin": "^3.0.2",
 | 
			
		||||
    "font-awesome-svg-png": "^1.2.2",
 | 
			
		||||
    "glob": "^7.1.2",
 | 
			
		||||
    "idb-keyval": "^2.3.0",
 | 
			
		||||
    "idb": "^2.0.4",
 | 
			
		||||
    "node-fetch": "^1.7.3",
 | 
			
		||||
    "node-sass": "^4.7.2",
 | 
			
		||||
    "npm-run-all": "^4.1.2",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,11 +5,11 @@
 | 
			
		|||
    </svg>
 | 
			
		||||
    <h1>Pinafore</h1>
 | 
			
		||||
  </div>
 | 
			
		||||
  <p>Pinafore is a web client for <a href="https://joinmastodon.org">Mastodon</a>, optimized for speed and simplicity.</p>
 | 
			
		||||
  <p>Pinafore is a web client for <a rel="noopener" target="_blank" href="https://joinmastodon.org">Mastodon</a>, optimized for speed and simplicity.</p>
 | 
			
		||||
 | 
			
		||||
  <p>To get started, <a href="/settings/instances/add">log in to an instance</a>.</p>
 | 
			
		||||
 | 
			
		||||
  <p>Don't have an instance? <a href="https://joinmastodon.org">Join Mastodon!</a></p>
 | 
			
		||||
  <p>Don't have an instance? <a rel="noopener" target="_blank" href="https://joinmastodon.org">Join Mastodon!</a></p>
 | 
			
		||||
</FreeTextLayout>
 | 
			
		||||
<style>
 | 
			
		||||
  .banner {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@
 | 
			
		|||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
  import { store } from '../_utils/store'
 | 
			
		||||
  import { getHomeTimeline } from '../_utils/mastodon'
 | 
			
		||||
  import { getHomeTimeline } from '../_utils/mastodon/oauth'
 | 
			
		||||
  import fixture from '../_utils/fixture.json'
 | 
			
		||||
  import Status from './Status.html'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										27
									
								
								routes/_utils/ajax.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								routes/_utils/ajax.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
export async function post(url, body) {
 | 
			
		||||
  return await (await fetch(url, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Accept': 'application/json',
 | 
			
		||||
      'Content-Type': 'application/json'
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify(body)
 | 
			
		||||
  })).json()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function paramsString(paramsObject) {
 | 
			
		||||
  let params = new URLSearchParams()
 | 
			
		||||
  Object.keys(paramsObject).forEach(key => {
 | 
			
		||||
    params.set(key, paramsObject[value])
 | 
			
		||||
  })
 | 
			
		||||
  return params.toString()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export async function get(url, headers = {}) {
 | 
			
		||||
  return await (await fetch(url, {
 | 
			
		||||
    method: 'GET',
 | 
			
		||||
    headers: Object.assign(headers, {
 | 
			
		||||
      'Accept': 'application/json',
 | 
			
		||||
    })
 | 
			
		||||
  })).json()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,21 +0,0 @@
 | 
			
		|||
import idbKeyVal from 'idb-keyval'
 | 
			
		||||
import { blobToBase64 } from '../_utils/binary'
 | 
			
		||||
 | 
			
		||||
let databasePromise
 | 
			
		||||
 | 
			
		||||
if (process.browser) {
 | 
			
		||||
  databasePromise = Promise.resolve().then(async () => {
 | 
			
		||||
    let token = await idbKeyVal.get('secure_token')
 | 
			
		||||
    if (!token) {
 | 
			
		||||
      let array = new Uint32Array(1028)
 | 
			
		||||
      crypto.getRandomValues(array);
 | 
			
		||||
      let token = await blobToBase64(new Blob([array]))
 | 
			
		||||
      await idbKeyVal.set('secure_token', token)
 | 
			
		||||
    }
 | 
			
		||||
    return idbKeyVal
 | 
			
		||||
  })
 | 
			
		||||
} else {
 | 
			
		||||
  databasePromise = Promise.resolve()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { databasePromise }
 | 
			
		||||
							
								
								
									
										2
									
								
								routes/_utils/database/database.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								routes/_utils/database/database.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
import keyval from './idb-keyval'
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										57
									
								
								routes/_utils/database/idb-keyval.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								routes/_utils/database/idb-keyval.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
import idb from 'idb'
 | 
			
		||||
 | 
			
		||||
// copypasta'd from https://github.com/jakearchibald/idb#keyval-store
 | 
			
		||||
 | 
			
		||||
const dbPromise = idb.open('keyval-store', 1, upgradeDB => {
 | 
			
		||||
  upgradeDB.createObjectStore('keyval')
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
const idbKeyval = {
 | 
			
		||||
  get(key) {
 | 
			
		||||
    return dbPromise.then(db => {
 | 
			
		||||
      return db.transaction('keyval').objectStore('keyval').get(key)
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  set(key, val) {
 | 
			
		||||
    return dbPromise.then(db => {
 | 
			
		||||
      const tx = db.transaction('keyval', 'readwrite')
 | 
			
		||||
      tx.objectStore('keyval').put(val, key)
 | 
			
		||||
      return tx.complete
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  delete(key) {
 | 
			
		||||
    return dbPromise.then(db => {
 | 
			
		||||
      const tx = db.transaction('keyval', 'readwrite')
 | 
			
		||||
      tx.objectStore('keyval').delete(key)
 | 
			
		||||
      return tx.complete
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  clear() {
 | 
			
		||||
    return dbPromise.then(db => {
 | 
			
		||||
      const tx = db.transaction('keyval', 'readwrite')
 | 
			
		||||
      tx.objectStore('keyval').clear()
 | 
			
		||||
      return tx.complete
 | 
			
		||||
    })
 | 
			
		||||
  },
 | 
			
		||||
  keys() {
 | 
			
		||||
    return dbPromise.then(db => {
 | 
			
		||||
      const tx = db.transaction('keyval')
 | 
			
		||||
      const keys = []
 | 
			
		||||
      const store = tx.objectStore('keyval')
 | 
			
		||||
      // This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
 | 
			
		||||
      // openKeyCursor isn't supported by Safari, so we fall back
 | 
			
		||||
      const iterate = store.iterateKeyCursor || store.iterateCursor
 | 
			
		||||
      iterate.call(store, cursor => {
 | 
			
		||||
        if (!cursor) {
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        keys.push(cursor.key)
 | 
			
		||||
        cursor.continue()
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
      return tx.complete.then(() => keys)
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default idbKeyval
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
const WEBSITE = 'https://pinafore.social'
 | 
			
		||||
const REDIRECT_URI = (typeof location !== 'undefined' ? location.origin : 'https://pinafore.social') + '/settings/instances/add'
 | 
			
		||||
const SCOPES = 'read write follow'
 | 
			
		||||
const CLIENT_NAME = 'Pinafore'
 | 
			
		||||
 | 
			
		||||
export function registerApplication(instanceName) {
 | 
			
		||||
  const url = `https://${instanceName}/api/v1/apps`
 | 
			
		||||
  return fetch(url, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Accept': 'application/json',
 | 
			
		||||
      'Content-Type': 'application/json'
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify({
 | 
			
		||||
      client_name: CLIENT_NAME,
 | 
			
		||||
      redirect_uris: REDIRECT_URI,
 | 
			
		||||
      scopes: SCOPES,
 | 
			
		||||
      website: WEBSITE
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function generateAuthLink(instanceName, clientId) {
 | 
			
		||||
  let url = `https://${instanceName}/oauth/authorize`
 | 
			
		||||
 | 
			
		||||
  let params = new URLSearchParams()
 | 
			
		||||
  params.set('client_id', clientId)
 | 
			
		||||
  params.set('redirect_uri', REDIRECT_URI)
 | 
			
		||||
  params.set('response_type', 'code')
 | 
			
		||||
  params.set('scope', SCOPES)
 | 
			
		||||
  url += '?' + params.toString()
 | 
			
		||||
  return url
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getAccessTokenFromAuthCode(instanceName, clientId, clientSecret, code) {
 | 
			
		||||
  let url = `https://${instanceName}/oauth/token`
 | 
			
		||||
  return fetch(url, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Accept': 'application/json',
 | 
			
		||||
      'Content-Type': 'application/json'
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify({
 | 
			
		||||
      client_id: clientId,
 | 
			
		||||
      client_secret: clientSecret,
 | 
			
		||||
      redirect_uri: REDIRECT_URI,
 | 
			
		||||
      grant_type: 'authorization_code',
 | 
			
		||||
      code: code
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getHomeTimeline(instanceName, accessToken) {
 | 
			
		||||
  let url = `https://${instanceName}/api/v1/timelines/home`
 | 
			
		||||
  return fetch(url, {
 | 
			
		||||
    method: 'GET',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Accept': 'application/json',
 | 
			
		||||
      'Authorization': `Bearer ${accessToken}`
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								routes/_utils/mastodon/oauth.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								routes/_utils/mastodon/oauth.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
const WEBSITE = 'https://pinafore.social'
 | 
			
		||||
const REDIRECT_URI = (typeof location !== 'undefined' ? location.origin : 'https://pinafore.social') + '/settings/instances'
 | 
			
		||||
const SCOPES = 'read write follow'
 | 
			
		||||
const CLIENT_NAME = 'Pinafore'
 | 
			
		||||
import { post, get, paramsString } from '../ajax'
 | 
			
		||||
 | 
			
		||||
export function registerApplication(instanceName) {
 | 
			
		||||
  const url = `https://${instanceName}/api/v1/apps`
 | 
			
		||||
  return post(url, {
 | 
			
		||||
      client_name: CLIENT_NAME,
 | 
			
		||||
      redirect_uris: REDIRECT_URI,
 | 
			
		||||
      scopes: SCOPES,
 | 
			
		||||
      website: WEBSITE
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function generateAuthLink(instanceName, clientId) {
 | 
			
		||||
  let params = paramsString({
 | 
			
		||||
    'client_id': clientId,
 | 
			
		||||
    'redirect_uri': REDIRECT_URI,
 | 
			
		||||
    'response_type': 'code',
 | 
			
		||||
    'scope': SCOPES
 | 
			
		||||
  })
 | 
			
		||||
  return `https://${instanceName}/oauth/authorize?${params}`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getAccessTokenFromAuthCode(instanceName, clientId, clientSecret, code) {
 | 
			
		||||
  let url = `https://${instanceName}/oauth/token`
 | 
			
		||||
  return post(url, {
 | 
			
		||||
    client_id: clientId,
 | 
			
		||||
    client_secret: clientSecret,
 | 
			
		||||
    redirect_uri: REDIRECT_URI,
 | 
			
		||||
    grant_type: 'authorization_code',
 | 
			
		||||
    code: code
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getHomeTimeline(instanceName, accessToken) {
 | 
			
		||||
  let url = `https://${instanceName}/api/v1/timelines/home`
 | 
			
		||||
  return get(url, {
 | 
			
		||||
    'Authorization': `Bearer ${accessToken}`
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								routes/_utils/mastodon/user.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								routes/_utils/mastodon/user.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
import { get } from '../ajax'
 | 
			
		||||
 | 
			
		||||
export function getCurrentUser(instanceName, accessToken) {
 | 
			
		||||
  let url = `https://${instanceName}/api/v1/accounts/verify_credentials`
 | 
			
		||||
  return get(url, {
 | 
			
		||||
    'Authorization': `Bearer ${accessToken}`
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +65,15 @@ store.compute(
 | 
			
		|||
  }
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
store.compute(
 | 
			
		||||
  'currentInstanceData',
 | 
			
		||||
  ['currentInstance', 'loggedInInstances'],
 | 
			
		||||
  (currentInstance, loggedInInstances) => {
 | 
			
		||||
    return Object.assign({
 | 
			
		||||
      name: currentInstance
 | 
			
		||||
    }, loggedInInstances[currentInstance])
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
if (process.browser && process.env.NODE_ENV !== 'production') {
 | 
			
		||||
  window.store = store // for debugging
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,6 +12,9 @@
 | 
			
		|||
  :global(.settings .free-text h1) {
 | 
			
		||||
    margin-bottom: 30px;
 | 
			
		||||
  }
 | 
			
		||||
  :global(.settings .free-text h2) {
 | 
			
		||||
    margin: 20px 0 10px;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
  import SettingsNav from './SettingsNav.html';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,18 +5,78 @@
 | 
			
		|||
<Layout page='settings'>
 | 
			
		||||
  <SettingsLayout page='settings/instances/{{params.instanceName}}' label="{{params.instanceName}}">
 | 
			
		||||
    <h1>{{params.instanceName}}</h1>
 | 
			
		||||
 | 
			
		||||
    {{#if currentUser}}
 | 
			
		||||
    <h2>Logged in as:</h2>
 | 
			
		||||
    <div class="current-user">
 | 
			
		||||
      <img src="{{currentUser.avatar}}" />
 | 
			
		||||
      <a rel="noopener" target="_blank" href="{{currentUser.url}}">@{{currentUser.acct}}</a>
 | 
			
		||||
      <span class="acct-name">{{currentUser.display_name}}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
    <h2>Theme:</h2>
 | 
			
		||||
    <form class="theme-chooser">
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-default" value="default">
 | 
			
		||||
        <label for="theme-default">Royal (default)</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-crimson"
 | 
			
		||||
               value="crimson">
 | 
			
		||||
        <label for="theme-crimson">Crimson and Clover</label>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="theme-group">
 | 
			
		||||
        <input type="radio" name="current-theme" id="theme-hotpants"
 | 
			
		||||
               value="hotpants">
 | 
			
		||||
        <label for="theme-hotpants">Hot Pants</label>
 | 
			
		||||
      </div>
 | 
			
		||||
    </form>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
  </SettingsLayout>
 | 
			
		||||
</Layout>
 | 
			
		||||
<style>
 | 
			
		||||
  .current-user {
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
    font-size: 1.3em;
 | 
			
		||||
  }
 | 
			
		||||
  .current-user img {
 | 
			
		||||
    width: 64px;
 | 
			
		||||
    height: 64px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
  }
 | 
			
		||||
  .current-user img, .current-user a, .current-user span {
 | 
			
		||||
    margin-right: 20px;
 | 
			
		||||
  }
 | 
			
		||||
  .theme-chooser {
 | 
			
		||||
    display: block;
 | 
			
		||||
    padding: 20px;
 | 
			
		||||
    line-height: 2em;
 | 
			
		||||
  }
 | 
			
		||||
  .theme-group {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
  }
 | 
			
		||||
  .theme-chooser label {
 | 
			
		||||
    margin: 2px 10px 0;
 | 
			
		||||
  }
 | 
			
		||||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
  import { store } from '../../_utils/store'
 | 
			
		||||
  import Layout from '../../_components/Layout.html'
 | 
			
		||||
  import SettingsLayout from '../_components/SettingsLayout.html'
 | 
			
		||||
  import { getCurrentUser } from '../../_utils/mastodon/user'
 | 
			
		||||
 | 
			
		||||
  export default {
 | 
			
		||||
    components: {
 | 
			
		||||
      Layout,
 | 
			
		||||
      SettingsLayout
 | 
			
		||||
    },
 | 
			
		||||
    store: () => store
 | 
			
		||||
    store: () => store,
 | 
			
		||||
    oncreate: async function () {
 | 
			
		||||
      let currentInstanceData = this.store.get('currentInstanceData')
 | 
			
		||||
      let currentUser = await getCurrentUser(currentInstanceData.name, currentInstanceData.access_token)
 | 
			
		||||
      this.set({currentUser: currentUser})
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@
 | 
			
		|||
    </form>
 | 
			
		||||
 | 
			
		||||
    {{#if !$isUserLoggedIn}}
 | 
			
		||||
    <p>Don't have an instance? <a href="https://joinmastodon.org">Join Mastodon!</a></p>
 | 
			
		||||
    <p>Don't have an instance? <a rel="noopener" target="_blank" href="https://joinmastodon.org">Join Mastodon!</a></p>
 | 
			
		||||
    {{/if}}
 | 
			
		||||
  </SettingsLayout>
 | 
			
		||||
</Layout>
 | 
			
		||||
| 
						 | 
				
			
			@ -49,8 +49,7 @@
 | 
			
		|||
<script>
 | 
			
		||||
  import Layout from '../../_components/Layout.html';
 | 
			
		||||
  import SettingsLayout from '../_components/SettingsLayout.html'
 | 
			
		||||
  import { registerApplication, generateAuthLink, getAccessTokenFromAuthCode } from '../../_utils/mastodon'
 | 
			
		||||
  import { databasePromise } from '../../_utils/database'
 | 
			
		||||
  import { registerApplication, generateAuthLink, getAccessTokenFromAuthCode } from '../../_utils/mastodon/oauth'
 | 
			
		||||
  import { store } from '../../_utils/store'
 | 
			
		||||
  import { goto } from 'sapper/runtime.js'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -74,12 +73,12 @@
 | 
			
		|||
      onReceivedOauthCode: async function(code) {
 | 
			
		||||
        let currentRegisteredInstanceName = this.store.get('currentRegisteredInstanceName')
 | 
			
		||||
        let currentRegisteredInstance = this.store.get('currentRegisteredInstance')
 | 
			
		||||
        let instanceData = await (await getAccessTokenFromAuthCode(
 | 
			
		||||
        let instanceData = await getAccessTokenFromAuthCode(
 | 
			
		||||
          currentRegisteredInstanceName,
 | 
			
		||||
          currentRegisteredInstance.client_id,
 | 
			
		||||
          currentRegisteredInstance.client_secret,
 | 
			
		||||
          code
 | 
			
		||||
        )).json()
 | 
			
		||||
        )
 | 
			
		||||
        // TODO: handle error
 | 
			
		||||
        let loggedInInstances = this.store.get('loggedInInstances')
 | 
			
		||||
        let loggedInInstancesInOrder = this.store.get('loggedInInstancesInOrder')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue