[feat] add mobile writer support
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { BaseDirectory, readBinaryFile, readDir, writeBinaryFile } from "@tauri-apps/api/fs";
|
import { BaseDirectory, readBinaryFile, readDir, writeBinaryFile } from "@tauri-apps/api/fs";
|
||||||
import { alertError, alertNormal, alertStore, alertWait } from "../alert";
|
import { alertError, alertNormal, alertStore, alertWait } from "../alert";
|
||||||
import { forageStorage, isTauri } from "../storage/globalApi";
|
import { LocalWriter, forageStorage, isTauri } from "../storage/globalApi";
|
||||||
import { decodeRisuSave, encodeRisuSave } from "../storage/risuSave";
|
import { decodeRisuSave, encodeRisuSave } from "../storage/risuSave";
|
||||||
import { get } from "svelte/store";
|
import { get } from "svelte/store";
|
||||||
import { DataBase } from "../storage/database";
|
import { DataBase } from "../storage/database";
|
||||||
@@ -9,25 +9,6 @@ import { relaunch } from "@tauri-apps/api/process";
|
|||||||
import { sleep } from "../util";
|
import { sleep } from "../util";
|
||||||
import { hubURL } from "../characterCards";
|
import { hubURL } from "../characterCards";
|
||||||
|
|
||||||
class TauriWriter{
|
|
||||||
path: string
|
|
||||||
firstWrite: boolean = true
|
|
||||||
constructor(path: string){
|
|
||||||
this.path = path
|
|
||||||
}
|
|
||||||
|
|
||||||
async write(data:Uint8Array) {
|
|
||||||
await writeBinaryFile(this.path, data, {
|
|
||||||
append: !this.firstWrite
|
|
||||||
})
|
|
||||||
this.firstWrite = false
|
|
||||||
}
|
|
||||||
|
|
||||||
async close(){
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBasename(data:string){
|
function getBasename(data:string){
|
||||||
const baseNameRegex = /\\/g
|
const baseNameRegex = /\\/g
|
||||||
const splited = data.replace(baseNameRegex, '/').split('/')
|
const splited = data.replace(baseNameRegex, '/').split('/')
|
||||||
@@ -35,42 +16,6 @@ function getBasename(data:string){
|
|||||||
return lasts
|
return lasts
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalWriter{
|
|
||||||
writableStream: WritableStream
|
|
||||||
writer: WritableStreamDefaultWriter|TauriWriter
|
|
||||||
async init() {
|
|
||||||
if(isTauri){
|
|
||||||
const filePath = await save({
|
|
||||||
filters: [{
|
|
||||||
name: 'Binary',
|
|
||||||
extensions: ['bin']
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
if(!filePath){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
this.writer = new TauriWriter(filePath)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
const streamSaver = await import('streamsaver')
|
|
||||||
this.writableStream = streamSaver.createWriteStream('risu-backup.bin')
|
|
||||||
this.writer = this.writableStream.getWriter()
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
async write(name:string,data: Uint8Array){
|
|
||||||
const encodedName = new TextEncoder().encode(getBasename(name))
|
|
||||||
const nameLength = new Uint32Array([encodedName.byteLength])
|
|
||||||
await this.writer.write(new Uint8Array(nameLength.buffer))
|
|
||||||
await this.writer.write(encodedName)
|
|
||||||
const dataLength = new Uint32Array([data.byteLength])
|
|
||||||
await this.writer.write(new Uint8Array(dataLength.buffer))
|
|
||||||
await this.writer.write(data)
|
|
||||||
}
|
|
||||||
async close(){
|
|
||||||
await this.writer.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export async function SaveLocalBackup(){
|
export async function SaveLocalBackup(){
|
||||||
alertWait("Saving local backup...")
|
alertWait("Saving local backup...")
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { updateColorScheme, updateTextTheme } from "../gui/colorscheme";
|
|||||||
import { saveDbKei } from "../kei/backup";
|
import { saveDbKei } from "../kei/backup";
|
||||||
import { Capacitor, CapacitorHttp } from '@capacitor/core';
|
import { Capacitor, CapacitorHttp } from '@capacitor/core';
|
||||||
import * as CapFS from '@capacitor/filesystem'
|
import * as CapFS from '@capacitor/filesystem'
|
||||||
|
import { save } from "@tauri-apps/api/dialog";
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
export const isTauri = !!window.__TAURI__
|
export const isTauri = !!window.__TAURI__
|
||||||
@@ -1112,4 +1113,98 @@ export function getModelMaxContext(model:string):number|undefined{
|
|||||||
}
|
}
|
||||||
|
|
||||||
return undefined
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
class TauriWriter{
|
||||||
|
path: string
|
||||||
|
firstWrite: boolean = true
|
||||||
|
constructor(path: string){
|
||||||
|
this.path = path
|
||||||
|
}
|
||||||
|
|
||||||
|
async write(data:Uint8Array) {
|
||||||
|
await writeBinaryFile(this.path, data, {
|
||||||
|
append: !this.firstWrite
|
||||||
|
})
|
||||||
|
this.firstWrite = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async close(){
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MobileWriter{
|
||||||
|
path: string
|
||||||
|
firstWrite: boolean = true
|
||||||
|
constructor(path: string){
|
||||||
|
this.path = path
|
||||||
|
}
|
||||||
|
|
||||||
|
async write(data:Uint8Array) {
|
||||||
|
if(this.firstWrite){
|
||||||
|
if(!await CapFS.Filesystem.checkPermissions()){
|
||||||
|
await CapFS.Filesystem.requestPermissions()
|
||||||
|
}
|
||||||
|
await CapFS.Filesystem.writeFile({
|
||||||
|
path: this.path,
|
||||||
|
data: Buffer.from(data).toString('base64'),
|
||||||
|
recursive: true,
|
||||||
|
directory: CapFS.Directory.Documents
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
await CapFS.Filesystem.appendFile({
|
||||||
|
path: this.path,
|
||||||
|
data: Buffer.from(data).toString('base64'),
|
||||||
|
directory: CapFS.Directory.Documents
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.firstWrite = false
|
||||||
|
}
|
||||||
|
|
||||||
|
async close(){
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export class LocalWriter{
|
||||||
|
writer: WritableStreamDefaultWriter|TauriWriter|MobileWriter
|
||||||
|
async init() {
|
||||||
|
if(isTauri){
|
||||||
|
const filePath = await save({
|
||||||
|
filters: [{
|
||||||
|
name: 'Binary',
|
||||||
|
extensions: ['bin']
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
if(!filePath){
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
this.writer = new TauriWriter(filePath)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if(Capacitor.isNativePlatform()){
|
||||||
|
this.writer = new MobileWriter('risu-backup.bin')
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
const streamSaver = await import('streamsaver')
|
||||||
|
const writableStream = streamSaver.createWriteStream('risu-backup.bin')
|
||||||
|
this.writer = writableStream.getWriter()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
async write(name:string,data: Uint8Array){
|
||||||
|
const encodedName = new TextEncoder().encode(getBasename(name))
|
||||||
|
const nameLength = new Uint32Array([encodedName.byteLength])
|
||||||
|
await this.writer.write(new Uint8Array(nameLength.buffer))
|
||||||
|
await this.writer.write(encodedName)
|
||||||
|
const dataLength = new Uint32Array([data.byteLength])
|
||||||
|
await this.writer.write(new Uint8Array(dataLength.buffer))
|
||||||
|
await this.writer.write(data)
|
||||||
|
}
|
||||||
|
async close(){
|
||||||
|
await this.writer.close()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user