import {store} from "../store/store.js" import * as lsm from "../lsm.js" import {resolveMxc} from "../functions.js" let lastBatch = null function sync() { const url = new URL(`${lsm.get("domain")}/_matrix/client/r0/sync`) url.searchParams.append("access_token", lsm.get("access_token")) const filter = { room: { // pulling more from the timeline massively increases download size timeline: { limit: 5 }, // members are not currently needed state: { lazy_load_members: true } }, presence: { // presence is not implemented, ignore it types: [] } } url.searchParams.append("filter", JSON.stringify(filter)) url.searchParams.append("timeout", 20000) if (lastBatch) { url.searchParams.append("since", lastBatch) } return fetch(url.toString()).then(res => res.json()).then(root => { lastBatch = root.next_batch return root }) } function manageSync(root) { try { let newEvents = false // set up directs const directs = root.account_data.events.find(e => e.type === "m.direct") if (directs) { Object.values(directs.content).forEach(ids => { ids.forEach(id => store.directs.add(id)) }) } // set up rooms Object.entries(root.rooms.join).forEach(([id, room]) => { if (!store.rooms.has(id)) { store.rooms.askAdd(id, room) } const storeRoom = store.rooms.get(id).value() room.state.events.forEach(event => { if (event.type === "m.room.member") { storeRoom.members.get(event.state_key).set(event) } }) const timeline = storeRoom.timeline if (room.timeline.events.length) newEvents = true timeline.updateEvents(room.timeline.events) }) // set up groups Promise.all( Object.keys(root.groups.join).map(id => { if (!store.groups.has(id)) { return Promise.all(["profile", "rooms"].map(path => { const url = new URL(`${lsm.get("domain")}/_matrix/client/r0/groups/${id}/${path}`) url.searchParams.append("access_token", lsm.get("access_token")) return fetch(url.toString()).then(res => res.json()) })).then(([profile, rooms]) => { rooms = rooms.chunk let order = 999 let orderEvent = root.account_data.events.find(e => e.type === "im.vector.web.tag_ordering") if (orderEvent) { if (orderEvent.content.tags.includes(id)) { order = orderEvent.content.tags.indexOf(id) } } const data = { name: profile.name, icon: resolveMxc(profile.avatar_url, 96, "crop"), order } store.groups.askAdd(id, data) rooms.forEach(groupRoom => { if (store.rooms.has(groupRoom.room_id)) { store.rooms.get(groupRoom.room_id).value().setGroup(id) } }) }) } }) ).then(() => { store.rooms.sort() }) if (newEvents) store.newEvents.broadcast("changeSelf") } catch (e) { console.error(root) throw e } } function syncLoop() { return sync().then(manageSync).then(syncLoop) } ;[ { id: "directs", name: "Directs", icon: "/static/directs.svg", order: -2 }, { id: "channels", name: "Channels", icon: "/static/channels.svg", order: -1 } ].forEach(data => store.groups.askAdd(data.id, data)) store.activeGroup.set(store.groups.get("directs").value()) syncLoop()