import {Message as MessageImpl} from '../chat/common'; import core from '../chat/core'; import {Conversation, Logs as Logging, Settings} from '../chat/interfaces'; declare global { const NativeFile: { read(name: string): Promise write(name: string, data: string): Promise listDirectories(name: string): Promise listFiles(name: string): Promise getSize(name: string): Promise ensureDirectory(name: string): Promise }; type NativeMessage = {time: number, type: number, sender: string, text: string}; const NativeLogs: { init(character: string): Promise logMessage(key: string, conversation: string, time: number, type: Conversation.Message.Type, sender: string, message: string): Promise; getBacklog(key: string): Promise>; getLogs(key: string, date: number): Promise> }; } const dayMs = 86400000; export const appVersion = (<{version: string}>require('./package.json')).version; //tslint:disable-line:no-require-imports export class GeneralSettings { account = ''; password = ''; host = 'wss://chat.f-list.net:9799'; theme = 'default'; version = appVersion; } type Index = {[key: string]: {name: string, dates: number[]} | undefined}; export class Logs implements Logging.Persistent { private index: Index = {}; constructor() { core.connection.onEvent('connecting', async() => { this.index = await NativeLogs.init(core.connection.character); }); } async logMessage(conversation: Conversation, message: Conversation.Message): Promise { const time = message.time.getTime(); const date = Math.floor(time / dayMs); let index = this.index[conversation.key]; if(index === undefined) index = this.index[conversation.key] = {name: conversation.name, dates: []}; if(index.dates[index.dates.length - 1] !== date) index.dates.push(date); return NativeLogs.logMessage(conversation.key, conversation.name, time / 1000, message.type, message.type === Conversation.Message.Type.Event ? '' : message.sender.name, message.text); } async getBacklog(conversation: Conversation): Promise> { return (await NativeLogs.getBacklog(conversation.key)) .map((x) => new MessageImpl(x.type, core.characters.get(x.sender), x.text, new Date(x.time * 1000))); } async getLogs(key: string, date: Date): Promise> { return (await NativeLogs.getLogs(key, date.getTime() / dayMs)) .map((x) => new MessageImpl(x.type, core.characters.get(x.sender), x.text, new Date(x.time * 1000))); } getLogDates(key: string): ReadonlyArray { const entry = this.index[key]; if(entry === undefined) return []; return entry.dates.map((x) => new Date(x * dayMs)); } get conversations(): ReadonlyArray<{id: string, name: string}> { const conversations: {id: string, name: string}[] = []; for(const key in this.index) conversations.push({id: key, name: this.index[key]!.name}); conversations.sort((x, y) => (x.name < y.name ? -1 : (x.name > y.name ? 1 : 0))); return conversations; } } export async function getGeneralSettings(): Promise { const file = await NativeFile.read('!settings'); if(file === undefined) return undefined; return JSON.parse(file); } export async function setGeneralSettings(value: GeneralSettings): Promise { return NativeFile.write('!settings', JSON.stringify(value)); } export class SettingsStore implements Settings.Store { async get(key: K, character: string = core.connection.character): Promise { const file = await NativeFile.read(`${character}/${key}`); if(file === undefined) return undefined; return JSON.parse(file); } async set(key: K, value: Settings.Keys[K]): Promise { return NativeFile.write(`${core.connection.character}/${key}`, JSON.stringify(value)); } async getAvailableCharacters(): Promise { return NativeFile.listDirectories('/'); } }