123 lines
3.9 KiB
HTML
123 lines
3.9 KiB
HTML
<:Head>
|
|
<title>Instances</title>
|
|
</:Head>
|
|
|
|
<Layout page='settings'>
|
|
<SettingsLayout page='instances'>
|
|
<h1>Instances</h1>
|
|
|
|
{{#if $isUserLoggedIn}}
|
|
<ul class="instances-list">
|
|
{{#each $loggedInInstancesAsList as instance}}
|
|
<li class="instance-card">
|
|
<span>{{instance.name}}</span>
|
|
</li>
|
|
{{/each}}
|
|
</ul>
|
|
{{else}}
|
|
<p>Connect to an instance to start using Pinafore.</p>
|
|
{{/if}}
|
|
|
|
{{#if !$isUserLoggedIn}}
|
|
<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">Add instance</button>
|
|
</form>
|
|
{{/if}}
|
|
|
|
{{#if !$isUserLoggedIn}}
|
|
<p>Don't have an instance? <a href="https://joinmastodon.org">Join Mastodon!</a></p>
|
|
{{/if}}
|
|
</SettingsLayout>
|
|
</Layout>
|
|
<style>
|
|
@media (max-width: 767px) {
|
|
input {
|
|
width: 90%;
|
|
}
|
|
}
|
|
|
|
input {
|
|
width: 250px;
|
|
}
|
|
|
|
form.add-new-instance {
|
|
background: var(--form-bg);
|
|
padding: 5px 10px 15px;
|
|
margin: 20px auto;
|
|
border: 1px solid var(--form-border);
|
|
}
|
|
|
|
form.add-new-instance label, form.add-new-instance input, form.add-new-instance button {
|
|
display: block;
|
|
margin: 20px 5px;
|
|
}
|
|
</style>
|
|
<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 { store } from '../_utils/store'
|
|
import { goto } from 'sapper/runtime.js'
|
|
|
|
export default {
|
|
oncreate: function () {
|
|
if (process.browser) {
|
|
(async () => {
|
|
let params = new URLSearchParams(location.search)
|
|
if (params.has('code')) {
|
|
this.onReceivedOauthCode(params.get('code'))
|
|
}
|
|
})()
|
|
}
|
|
},
|
|
components: {
|
|
Layout,
|
|
SettingsLayout
|
|
},
|
|
store: () => store,
|
|
methods: {
|
|
onReceivedOauthCode: async function(code) {
|
|
let currentRegisteredInstanceName = this.store.get('currentRegisteredInstanceName')
|
|
let currentRegisteredInstance = this.store.get('currentRegisteredInstance')
|
|
let instanceData = await (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')
|
|
loggedInInstances[currentRegisteredInstanceName] = instanceData
|
|
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
|
|
loggedInInstancesInOrder.push(currentRegisteredInstanceName)
|
|
}
|
|
this.store.set({
|
|
instanceNameInSearch: '',
|
|
loggedInInstances: loggedInInstances,
|
|
currentInstance: currentRegisteredInstanceName,
|
|
loggedInInstancesInOrder: loggedInInstancesInOrder
|
|
})
|
|
this.store.save()
|
|
goto('/')
|
|
},
|
|
onSubmit: async function(event) {
|
|
event.preventDefault()
|
|
let instanceName = this.store.get('instanceNameInSearch')
|
|
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
|
|
let instanceData = await (await registerApplication(instanceName)).json()
|
|
// TODO: handle error
|
|
this.store.set({
|
|
currentRegisteredInstanceName: instanceName,
|
|
currentRegisteredInstance: instanceData
|
|
})
|
|
this.store.save()
|
|
let oauthUrl = generateAuthLink(instanceName, instanceData.client_id)
|
|
document.location.href = oauthUrl
|
|
},
|
|
}
|
|
}
|
|
</script> |