pinafore/routes/settings/instances/add.html

164 lines
5.4 KiB
HTML
Raw Normal View History

2018-01-08 00:00:42 +00:00
<:Head>
2018-01-13 20:12:17 +00:00
<title>Add an Instance</title>
2018-01-08 00:00:42 +00:00
</:Head>
<Layout page='settings'>
2018-01-13 20:12:17 +00:00
<SettingsLayout page='settings/instances/add' label="Add an Instance">
<h1>Add an Instance</h1>
2018-01-08 00:00:42 +00:00
<LoadingMask show="{{loading}}"/>
{{#if $isUserLoggedIn}}
2018-01-13 20:12:17 +00:00
<p>Connect to an instance to log in.</p>
{{else}}
2018-01-13 20:12:17 +00:00
<p>Log in to an instance to start using Pinafore.</p>
{{/if}}
2018-01-08 00:00:42 +00:00
2018-01-13 20:12:17 +00:00
<form class="add-new-instance" on:submit='onSubmit(event)'>
<label for="instanceInput">Instance name:</label>
<input type="text" id="instanceInput" bind:value='$instanceNameInSearch' placeholder=''>
<button class="primary" type="submit" id="submitButton" disabled="{{!$instanceNameInSearch}}">Add instance</button>
2018-01-13 20:12:17 +00:00
</form>
2018-01-08 00:00:42 +00:00
{{#if !$isUserLoggedIn}}
2018-01-13 22:19:51 +00:00
<p>Don't have an instance? <a rel="noopener" target="_blank" href="https://joinmastodon.org">Join Mastodon!</a></p>
{{/if}}
2018-01-09 01:44:29 +00:00
</SettingsLayout>
2018-01-08 00:00:42 +00:00
</Layout>
<style>
2018-01-08 06:00:16 +00:00
@media (max-width: 767px) {
input {
width: 90%;
}
}
2018-01-08 00:00:42 +00:00
input {
2018-01-08 06:00:16 +00:00
width: 250px;
2018-01-08 00:00:42 +00:00
}
form.add-new-instance {
2018-01-12 17:01:46 +00:00
background: var(--form-bg);
2018-01-08 00:00:42 +00:00
padding: 5px 10px 15px;
2018-01-12 17:01:46 +00:00
margin: 20px auto;
border: 1px solid var(--form-border);
2018-01-08 00:00:42 +00:00
}
form.add-new-instance label, form.add-new-instance input, form.add-new-instance button {
2018-01-08 00:00:42 +00:00
display: block;
margin: 20px 5px;
}
</style>
<script>
2018-01-13 20:12:17 +00:00
import Layout from '../../_components/Layout.html';
import SettingsLayout from '../_components/SettingsLayout.html'
2018-01-13 22:19:51 +00:00
import { registerApplication, generateAuthLink, getAccessTokenFromAuthCode } from '../../_utils/mastodon/oauth'
2018-01-13 20:12:17 +00:00
import { store } from '../../_utils/store'
2018-01-08 06:13:15 +00:00
import { goto } from 'sapper/runtime.js'
2018-01-14 05:03:03 +00:00
import { switchToTheme } from '../../_utils/themeEngine'
import { toast } from '../../_utils/toast'
import LoadingMask from '../../_components/LoadingMask'
import { fade } from 'svelte-transitions'
2018-01-08 00:00:42 +00:00
2018-01-14 03:23:05 +00:00
const REDIRECT_URI = (typeof location !== 'undefined' ?
location.origin : 'https://pinafore.social') + '/settings/instances/add'
2018-01-08 00:00:42 +00:00
export default {
2018-01-08 06:00:16 +00:00
oncreate: function () {
if (process.browser) {
(async () => {
let params = new URLSearchParams(location.search)
if (params.has('code')) {
this.onReceivedOauthCode(params.get('code'))
2018-01-08 06:00:16 +00:00
}
})()
}
},
2018-01-08 00:00:42 +00:00
components: {
2018-01-09 01:44:29 +00:00
Layout,
SettingsLayout,
LoadingMask
2018-01-08 00:00:42 +00:00
},
store: () => store,
transitions: {
fade
},
2018-01-08 00:00:42 +00:00
methods: {
2018-01-14 02:59:49 +00:00
onSubmit: async function(event) {
event.preventDefault()
this.set({loading: true})
try {
await this.redirectToOauth()
} catch (err) {
if (process.env.NODE_ENV !== 'production') {
console.error(err)
}
toast.say(`Error: ${err.message || err.name}. Is this a valid Mastodon instance?`)
} finally {
this.set({loading: false})
}
},
redirectToOauth: async function() {
2018-01-14 02:59:49 +00:00
let instanceName = this.store.get('instanceNameInSearch')
let loggedInInstances = this.store.get('loggedInInstances')
2018-01-14 02:59:49 +00:00
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
if (Object.keys(loggedInInstances).includes(instanceName)) {
toast.say(`You've already logged in to ${instanceName}`)
return
}
2018-01-14 03:23:05 +00:00
let instanceData = await registerApplication(instanceName, REDIRECT_URI)
2018-01-14 02:59:49 +00:00
this.store.set({
currentRegisteredInstanceName: instanceName,
currentRegisteredInstance: instanceData
})
this.store.save()
2018-01-14 03:23:05 +00:00
let oauthUrl = generateAuthLink(
instanceName,
instanceData.client_id,
REDIRECT_URI
)
2018-01-14 02:59:49 +00:00
document.location.href = oauthUrl
},
onReceivedOauthCode: async function(code) {
try {
this.set({loading: true})
await this.registerNewInstance(code)
} catch (err) {
toast.say(`Error: ${err.message || err.name}. Failed to connect to instance.`)
} finally {
this.set({loading: false})
}
},
registerNewInstance: async function (code) {
2018-01-13 06:24:54 +00:00
let currentRegisteredInstanceName = this.store.get('currentRegisteredInstanceName')
let currentRegisteredInstance = this.store.get('currentRegisteredInstance')
2018-01-13 22:19:51 +00:00
let instanceData = await getAccessTokenFromAuthCode(
2018-01-13 06:24:54 +00:00
currentRegisteredInstanceName,
currentRegisteredInstance.client_id,
currentRegisteredInstance.client_secret,
2018-01-14 03:23:05 +00:00
code,
REDIRECT_URI
2018-01-13 22:19:51 +00:00
)
2018-01-13 06:24:54 +00:00
let loggedInInstances = this.store.get('loggedInInstances')
let loggedInInstancesInOrder = this.store.get('loggedInInstancesInOrder')
2018-01-14 04:07:11 +00:00
let instanceThemes = this.store.get('instanceThemes')
instanceThemes[currentRegisteredInstanceName] = 'default'
2018-01-13 06:24:54 +00:00
loggedInInstances[currentRegisteredInstanceName] = instanceData
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
loggedInInstancesInOrder.push(currentRegisteredInstanceName)
}
this.store.set({
2018-01-13 06:26:20 +00:00
instanceNameInSearch: '',
2018-01-14 02:59:49 +00:00
currentRegisteredInstanceName: null,
currentRegisteredInstance: null,
2018-01-13 06:26:20 +00:00
loggedInInstances: loggedInInstances,
currentInstance: currentRegisteredInstanceName,
2018-01-14 04:07:11 +00:00
loggedInInstancesInOrder: loggedInInstancesInOrder,
instanceThemes: instanceThemes
})
this.store.save()
2018-01-14 05:03:03 +00:00
switchToTheme('default')
goto('/')
}
2018-01-08 00:00:42 +00:00
}
}
</script>