Add roster screen
This allows you to view and start new conversations with contacts, although it doesn't let implement a sliding window or allow you to search through then.
This commit is contained in:
parent
1f7ad1408c
commit
c8f5240332
|
@ -7,6 +7,7 @@
|
|||
import Home from './routes/Home.svelte'
|
||||
import Login from './routes/Login.svelte'
|
||||
import Messages from './routes/Messages.svelte'
|
||||
import Contacts from './routes/Contacts.svelte'
|
||||
import Chat from './routes/Chat.svelte'
|
||||
import Redirect from './routes/Redirect.svelte'
|
||||
|
||||
|
@ -23,6 +24,7 @@
|
|||
'/': Home,
|
||||
'/login': Login,
|
||||
'/messages': Messages,
|
||||
'/contacts': Contacts,
|
||||
'/chat/:chatID': Chat,
|
||||
'*': Redirect,
|
||||
}
|
||||
|
|
122
src/routes/Contacts.svelte
Normal file
122
src/routes/Contacts.svelte
Normal file
|
@ -0,0 +1,122 @@
|
|||
<script lang="ts">
|
||||
import Text from '../components/Text.svelte'
|
||||
import ListItem from '../components/ListItem.svelte'
|
||||
|
||||
import { push, replace } from 'svelte-spa-router'
|
||||
import { _converse } from '@converse/headless/core'
|
||||
|
||||
import {
|
||||
titleStore,
|
||||
softkeysStore,
|
||||
xmppConnected,
|
||||
} from '../stores.ts'
|
||||
|
||||
titleStore.update(() => 'Contacts')
|
||||
|
||||
softkeysStore.update((k) => {
|
||||
k.left.label = 'Search'
|
||||
k.left.callback = () => {}
|
||||
|
||||
k.center.label = 'Chat'
|
||||
k.center.callback = () => {
|
||||
document.activeElement.click()
|
||||
}
|
||||
|
||||
k.right.label = 'Options'
|
||||
k.right.callback = () => {}
|
||||
|
||||
return k
|
||||
})
|
||||
|
||||
// Main function for this view: get a conversation going!
|
||||
function createChat(contactJID) {
|
||||
_converse.api.listen.on('chatBoxInitialized', model => {
|
||||
replace(`/chat/${model.id}`)
|
||||
})
|
||||
_converse.api.chats.create(contactJID)
|
||||
}
|
||||
|
||||
// Run this and unsubscribe after one
|
||||
// second. (The xmppConnected.subscribe function
|
||||
// returns the unsubscribe callback, which we
|
||||
// then call with setTimeout after 1000 ms)
|
||||
setTimeout(xmppConnected.subscribe(value => {
|
||||
if (!value) {
|
||||
push('/redirect') // redirects to home
|
||||
}
|
||||
}), 1000)
|
||||
|
||||
// Stores information on the rendered contacts
|
||||
let contacts = []
|
||||
let contactsRenderedAt = 0 // a very, very long time ago
|
||||
let contactsRendering = false // is a rendering scheduled?
|
||||
|
||||
// TODO: use a sliding window so that only the contacts
|
||||
// that are in view get rendered
|
||||
|
||||
// Helper function to convert contacts list into
|
||||
// (exceedingly lightweight) object array for
|
||||
// final rendering
|
||||
function contactsToArray(contacts) {
|
||||
return contacts.map(c => ({
|
||||
jid: c.attributes.jid,
|
||||
name: c.attributes.nickname || c.attributes.user_id,
|
||||
}))
|
||||
}
|
||||
|
||||
function renderContacts() {
|
||||
|
||||
// If there are no contacts, just render an empty array
|
||||
if (!_converse?.roster?.models) {
|
||||
contacts = []
|
||||
return
|
||||
}
|
||||
|
||||
// If the contacts were updated more than 5 seconds ago,
|
||||
// render them again immediately
|
||||
if (new Date() - contactsRenderedAt > 5000) {
|
||||
contacts = contactsToArray(_converse?.roster?.models)
|
||||
} else {
|
||||
// If they were updated less than 5 seconds ago, check
|
||||
// if a re-render has been scheduled
|
||||
if (contactsRendering) {
|
||||
return
|
||||
} else {
|
||||
contactsRendering = true
|
||||
|
||||
// Render them after a gap
|
||||
setTimeout(function () {
|
||||
contactsRendering = false
|
||||
contactsRenderedAt = new Date()
|
||||
renderContacts()
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render them once
|
||||
renderContacts()
|
||||
|
||||
_converse.on('rosterContactsFetched', () => {
|
||||
renderContacts()
|
||||
})
|
||||
|
||||
_converse.on('presence', () => {
|
||||
renderContacts()
|
||||
})
|
||||
</script>
|
||||
|
||||
{#if !contacts.length}
|
||||
<Text>
|
||||
<p>You have no contacts. How about adding one?</p>
|
||||
</Text>
|
||||
{:else}
|
||||
{#each contacts as contact, index (contact.jid)}
|
||||
<ListItem
|
||||
text={contact.name}
|
||||
subtext={contact.jid}
|
||||
tabindex={index}
|
||||
onclick={() => createChat(contact.jid)}
|
||||
/>
|
||||
{/each}
|
||||
{/if}
|
|
@ -54,7 +54,8 @@
|
|||
forward_messages: false,
|
||||
enable_smacks: true,
|
||||
allow_chat_pending_contacts: true,
|
||||
allow_non_roster_messaging: true,
|
||||
allow_non_roster_messaging: false,
|
||||
roster_groups: false,
|
||||
|
||||
// Special optimisations to reduce memory usage on KaiOS
|
||||
mam_request_all_pages: false,
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
titleStore.update(() => 'Convo')
|
||||
|
||||
softkeysStore.update((k) => {
|
||||
k.left.label = 'new'
|
||||
k.left.callback = () => {}
|
||||
k.left.label = 'New'
|
||||
k.left.callback = () => {
|
||||
push('/contacts')
|
||||
}
|
||||
|
||||
k.center.label = 'Open'
|
||||
k.center.callback = () => {
|
||||
|
|
Loading…
Reference in a new issue