Open
Description
什么时候能发布官方版本的apk呢?
对于能够运行油猴插件的PC和移动端浏览器(edge 移动端浏览器、X 浏览器、via……)可以使用以下脚本导入、导出app.nextchat.dev中的数据。
For PC and mobile browsers capable of running the Tampermonkey plugin (edge mobile browser, X browser, via...) The following script can be used to import and export the data in app.nextchat.dev.
我使用 flutter 制作了一个 app.nextchat.dev 的安卓临时代替品
编译后的apk:NextChatTempAPP
其他开源作者的flutter代码(我在其基础上进行了依赖更新、添加logo等,由于修改非常简单,应该不太需要公开源码) ChatGPT-Next-APP
I used flutter to create a temporary Android alternative for app.nextchat.dev
The compiled apk: NextChatTempAPP
flutter code from other open-source authors (I made dependency updates, added logos, etc. based on it. Since the modifications were very simple, Should not need to open source) ChatGPT-Next-APP
// ==UserScript==
// @name IndexedDB KeyVal Store导出、导入为JSON
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 将IndexedDB keyval-store存储桶中的全部数据导出下载为JSON,从JSON文件导入数据到IndexedDB keyval-store
// @author WorldDev
// @match *://*/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 延迟一秒执行
setTimeout(() => {
// 创建一个容器来放置按钮
const buttonContainer = document.createElement('div');
buttonContainer.style.position = 'fixed';
buttonContainer.style.top = '100px';
buttonContainer.style.left = '100px';
buttonContainer.style.zIndex = '9999';
buttonContainer.style.display = 'flex';
buttonContainer.style.flexDirection = 'column';
buttonContainer.style.gap = '0'; // 设置按钮无间隔
document.body.appendChild(buttonContainer);
// 创建导出按钮
const exportButton = document.createElement('button');
exportButton.id = 'exportButton';
exportButton.textContent = '导出数据为JSON';
buttonContainer.appendChild(exportButton);
// 创建导入按钮
const importButton = document.createElement('button');
importButton.id = 'importButton';
importButton.textContent = '从JSON导入数据';
buttonContainer.appendChild(importButton);
// 创建隐藏的文件输入元素用于导入
const fileInput = document.createElement('input');
fileInput.type = 'file';
fileInput.accept = '.json';
fileInput.style.display = 'none';
document.body.appendChild(fileInput);
// 绑定事件监听器
document.getElementById('exportButton').addEventListener('click', exportDataToJson);
document.getElementById('importButton').addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileSelect);
function openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('keyval-store');
request.onerror = event => reject(event.target.error);
request.onsuccess = event => resolve(event.target.result);
request.onupgradeneeded = event => {
const db = event.target.result;
if (!db.objectStoreNames.contains('keyval')) {
db.createObjectStore('keyval');
}
};
});
}
async function getAllData(db) {
const transaction = db.transaction(['keyval'], 'readonly');
const objectStore = transaction.objectStore('keyval');
const data = await getAllFromObjectStore(objectStore);
return data;
}
function getAllFromObjectStore(objectStore) {
return new Promise((resolve, reject) => {
const allItems = [];
const request = objectStore.openCursor();
request.onsuccess = event => {
const cursor = event.target.result;
if (cursor) {
allItems.push({ key: cursor.key, value: cursor.value });
cursor.continue();
} else {
resolve(allItems);
}
};
request.onerror = event => reject(event.target.error);
});
}
async function exportDataToJson() {
try {
const db = await openDatabase();
const data = await getAllData(db);
const jsonContent = JSON.stringify(data, null, 2);
downloadJson(jsonContent, 'indexeddb_data.json');
} catch (error) {
console.error('导出数据时出错:', error);
alert('导出数据失败,请检查控制台错误信息。');
}
}
function downloadJson(content, filename) {
const blob = new Blob([content], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
function handleFileSelect(event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.readAsText(file);
reader.onload = async e => {
try {
const jsonData = JSON.parse(e.target.result);
const db = await openDatabase();
await importDataToDb(db, jsonData);
alert('数据导入成功!');
} catch (error) {
console.error('导入数据时出错:', error);
alert('导入数据失败,请检查控制台错误信息。');
}
};
}
}
async function importDataToDb(db, data) {
const transaction = db.transaction(['keyval'], 'readwrite');
const objectStore = transaction.objectStore('keyval');
for (const item of data) {
objectStore.put(item.value, item.key);
}
return new Promise((resolve, reject) => {
transaction.oncomplete = () => resolve();
transaction.onerror = event => reject(event.target.error);
});
}
}, 1000); // 延迟1秒执行
})();
Metadata
Metadata
Assignees
Labels
No labels