Skip to content

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

Open
@gitgitTrue

Description

@gitgitTrue

什么时候能发布官方版本的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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions