NextChat icon indicating copy to clipboard operation
NextChat copied to clipboard

app.nextchat.dev 的 Android 临时代替品,官方Android apk什么时候能够发布呢?

Open gitgitTrue opened this issue 7 months ago • 0 comments

什么时候能发布官方版本的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秒执行
})();

gitgitTrue avatar Jun 28 '25 17:06 gitgitTrue