文字直播用 chatgpt 开发一个笔记软件。 希望可以在睡觉前部署上线。

2023-06-08 20:53:00 +08:00
 hamsterbase

下面是之前的聊天记录

Q: 我现在希望开发一个卡片笔记软件。UI 界面类似于 imessage 。 请问叫什么名字比较好?

A 为了取一个好名字,需要考虑软件的特点和目标用户。考虑到你的软件类似于 iMessage ,那么你可以考虑使用类似的命名方式。以下是一些可能的建议:

CardMessage NoteChat CardNote SnapNote MemoTalk NoteMessage 在考虑具体的名字时,可以考虑软件的品牌形象,功能特点等方面,以便从众多同类软件中脱颖而出

  1. 搜了一下,memo talk 之前没人开发过,就叫这个名字吧。

  2. 建了一个 GitHub 仓库 https://github.com/hamsterbase/memo-talk

Q: sha256 转化为字符串,长度是多少。

A:

SHA256 是一种加密算法,它生成的哈希值( hash value )通常表示为 64 个字符的十六进制字符串( hexadecimal string ),因此 SHA256 转化为字符串后的长度是 64 个字符。每个字符是 0-9 和 A-F 之间的一个 16 进制数字,因此它们可以表示 256 个可能的值( 16 的 4 次方)。

5

Q:

我希望你能帮我编写一下服务端的代码。

需要有以下四个接口接口为

  1. 获取文件夹列表

  2. 根据文件夹名字,文件名获取文件内容

  3. 根据文件夹名字,文件名删除文件

  4. 根据文件夹名字,文件名删除文件

要求。

  1. 基于 koa 编写
  2. 使用 typescript 编写
  3. 文件名,文件名必须为 64 个字符,每个字符是 0-9 和 A-F 之间的一个 16 进制数字
  4. 文件夹名和文件名,文件内容都通过 body 传递。

A: 以下是一个基于 Koa 和 TypeScript 的简单实现,其中包含了四个接口:

import Koa from "koa";
import bodyParser from "koa-bodyparser";

const app = new Koa();

// 定义文件夹列表
let folders: string[] = [];

// 定义文件内容
let files: { [key: string]: string } = {};

// 获取文件夹列表
app.use(async (ctx, next) => {
  if (ctx.path === "/folders" && ctx.method === "GET") {
    ctx.body = folders;
    ctx.status = 200;
  } else {
    await next();
  }
});

// 获取文件内容
app.use(async (ctx, next) => {
  if (ctx.path === "/files" && ctx.method === "GET") {
    const folderName = ctx.request.body.folderName;
    const fileName = ctx.request.body.fileName;
    const filePath = `${folderName}/${fileName}`;
    if (files[filePath]) {
      ctx.body = files[filePath];
      ctx.status = 200;
    } else {
      ctx.body = "File not found";
      ctx.status = 404;
    }
  } else {
    await next();
  }
});

// 添加文件
app.use(bodyParser());
app.use(async (ctx, next) => {
  if (ctx.path === "/files" && ctx.method === "POST") {
    const folderName = ctx.request.body.folderName;
    const fileName = ctx.request.body.fileName;
    const fileContent = ctx.request.body.fileContent;
    const filePath = `${folderName}/${fileName}`;
    if (files[filePath]) {
      ctx.body = "File already exists";
      ctx.status = 409;
    } else {
      files[filePath] = fileContent;
      ctx.status = 201;
    }
  } else {
    await next();
  }
});

// 删除文件
app.use(async (ctx, next) => {
  if (ctx.path === "/files" && ctx.method === "DELETE") {
    const folderName = ctx.request.body.folderName;
    const fileName = ctx.request.body.fileName;
    const filePath = `${folderName}/${fileName}`;
    if (files[filePath]) {
      delete files[filePath];
      ctx.status = 204;
    } else {
      ctx.body = "File not found";
      ctx.status = 404;
    }
  } else {
    await next();
  }
});

app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

请注意,此代码仅供参考,可能需要根据具体需求进行修改和调整。

3978 次点击
所在节点    分享创造
62 条回复
hamsterbase
2023-06-09 23:33:06 +08:00
```
class FileAPISDK {
constructor(baseUrl = "http://localhost:9999") {
this.baseUrl = baseUrl;
}

async getList(folder) {
const response = await fetch(`${this.baseUrl}/public/api/v1/folder`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ folder }),
});

this._handleErrors(response);
return await response.json();
}

async getFile(folder, file) {
const response = await fetch(`${this.baseUrl}/public/api/v1/file`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ folder, file }),
});

this._handleErrors(response);
return await response.text();
}

async deleteFile(folder, file) {
const response = await fetch(`${this.baseUrl}/public/api/v1/file`, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ folder, file }),
});

this._handleErrors(response);
return await response.text();
}

async createFile(folder, file, content) {
const response = await fetch(`${this.baseUrl}/public/api/v1/file`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ folder, file, content }),
});

this._handleErrors(response);
return await response.text();
}

_handleErrors(response) {
if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}
}
}
```
hamsterbase
2023-06-09 23:38:14 +08:00
14. 发现服务器忘记配置跨域了。

q:koajs 如何开启跨区请求。
hamsterbase
2023-06-10 00:11:08 +08:00
11. 服务器问题修复后,开始对接。 核心的云同步逻辑非常简单


const sdk = new FileAPISDK(url);

// 生成加密密钥
// userToken 用来标记用户身份,也是服务器文件夹的名字
// encryptionKey 是文件加密密码,encryptionKey 不会发送到服务
const { userToken, encryptionKey } = generateKeys(username, passowrd);

// 获取服务器数据库列表
const files: string[] = await sdk.getList(userToken);

const mergedFiles: string[] = [];

// 把服务器上的文件和本地合并,合并后加入等待删除列表
for (const file of files) {
try {
const remoteData = await sdk.getFile(userToken, file);
const database = decryptData(remoteData, encryptionKey);
memoTalkCore.merge(database);
mergedFiles.push(file);
} catch (error) {
console.log(error);
}
}

// 获取本地最新数据,加密
const currentData = encryptData(memoTalkCore.encode(), encryptionKey);
const fileName = sha256(currentData);

// 把加密后的文档存到服务器
await sdk.createFile(userToken, fileName, currentData);

// 因为数据已经合并到本地了,所以把服务器的删掉
for (const mergedFile of mergedFiles) {
try {
await sdk.deleteFile(userToken, mergedFile);
} catch (error) {
console.log(error);
}
}
}
hamsterbase
2023-06-10 00:22:54 +08:00
12. 经过 2 天 6 小时的开发。 一个本地优先的极简卡片笔记就开发完了。(只有最核心功能)

可以访问 https://memo-talk-web.onrender.com 体验

注意: 项目还没正式发布,只能拿来玩。,不要在这里储存任何数据。

1. 纯 web 实现, 压缩后不到 173 k 。
2. 支持离线编辑,再次联网后自动同步。
3. 两台设备输入相同的账户密码。 刷新页面刷新后,他们会自动同步到同一个状态。
4. 所有数据在本地加密,服务器不储存明文数据。
HulkLee
2023-06-10 15:04:34 +08:00
牛,面向 chatgpt 编程。
llsongll
2023-06-12 10:32:41 +08:00
nb ,我就想着有这种笔记,跟微信聊天似的,能搜索,快捷输入,(最好能匹配像是 alfred ,utools 这种工具,安卓可以一键输入。)
temberature
2023-06-12 13:20:29 +08:00
@llsongll 直接用微信不行吗 :)
llsongll
2023-06-12 20:03:36 +08:00
@temberature #47 微信不是有监测吗。。。而且微信以前有插件可以用 alfred 输入,现在好像不行了。
temberature
2023-06-13 15:46:36 +08:00
@llsongll 这些确实也都是问题。但反过来说,为什么要像微信聊天呢~没有这个要求有很多应用差不多吧
llsongll
2023-06-13 21:14:20 +08:00
@temberature #49 嗯呢,我也有用 Obsidian 的 memos ,也有类似的效果,alfred 也可以在不打开 ob 的情况下快捷输入。就是虽然界面体验比微信的感觉差了好多
temberature
2023-06-13 21:21:25 +08:00
@llsongll 具体能说出来界面差在哪里吗 :)
dvbs2000
2023-06-13 22:16:16 +08:00
能麻烦直接把对话的 url 共享出来么 谢谢~ gpt 现在是有共享功能的。直接就可以共享
coolcfan
2023-06-14 00:17:52 +08:00
@llsongll 之前推很大的 Flomo 是不是就是这种
llsongll
2023-06-14 09:38:54 +08:00
@coolcfan #53 类似,我说的 memos 就是 flome 差不多的开源版
llsongll
2023-06-14 10:31:28 +08:00
@temberature #51 我其实也说不出来个具体,可以简单描述下我需要的功能。比如 1 、微信的联系人可以看做 ob 不同的库,例:inbox ;剪藏;日记; note 等等,这个栏可折叠可隐藏可快捷键切换,我以前用 typora 时,就是分文件夹的,打标签的话,搜索的时候会多输入,再一个限制自己少分类,我一般都是用 alfred 搜索的,倒是无所谓,但是手机端搜索就会麻烦,这样会好点。
2 、输入框在下面,焦点永远在输入框内,在写长文的时候可放大输入框,隐藏聊天记录,写完发送自动显示聊天记录,恢复刚才的界面。
3 、消息框,右键复制、删除、引用、转发到其他库、多选
4 、图片、文件、文字,标签和多选批量打标签
5 、搜索:可在单独库搜索,可全部库搜索。可搜文件,图片,视频,链接,可日期排序。可定位到当时聊天的地方,可定位在 finder 中。微信或者 notion 那种弹出式搜索就非常舒服,ob 侧边栏搜索超级难受。
6 、显示问题,我是用笔记本的,比较少用台式,我认为屏幕太大,会分散焦点,在我 13 寸屏幕上,显示三分之二或者五分之三会是一个比较合适的大小。
---
以上这些应该是基本功能,下面我是常用的功能,每个笔记软件我都期待的。
1 、速度,我调教后的 ob ,使用了 6 个插件,一个小主题,因为老电脑所以打开还是比较慢,但是常驻后台会占用我为数不多的内存,所以,要么打开速度快,要么占用低,比较个人,穷逼的苦楚。
2 、快捷输入,mac:alfred 可以快捷输入到任何一个 md 文件中。手机端,启动软件后直接弹出输入框,因为要查看的话,不建议多点一下输入框外的部分,输入的话更需要快速,否则对于我这种老年人,怕不是过一会就忘了。。。
3 、mac 和手机端剪藏,这个感觉 md 的都不太好,所以我现在都手动复制,不太了解。
4 、本地。同步对我来说不是刚需,md 的同步都会被检测到,如何要同步反而数据库其实更安全。
5 、界面简洁好看,我的 ob 比微信界面还小,没有侧边栏,标签栏,全部都隐藏了,光秃秃的。
---
大概想的就是这些,我可能说的不太有逻辑性,你凑乎看看。。。其实刚需就只有快捷输入,和快捷搜索。其他的都是体验类,能忍受,但会随时想换一个试试。
temberature
2023-06-15 13:18:57 +08:00
@llsongll 我还在用 12 年的 mac :)
基础功能主要考验细节把控能力,微信到今天打磨的确实挺不错的。
我主要关注的还是核心需求,快分为两种,一种绝对值的快,类似技术性能上的参数;一种是能产生质变的快,笔记这件事,根本限制还是来自大脑的认知能力,人又不擅长同时处理多件事情,所以快可以让人集中应对更丰富内聚的内容。
llsongll
2023-06-17 19:26:47 +08:00
@temberature #56 哈哈哈,我在用 13 年的 mac 。你说的对,ob 、vc 等对于老电脑来说,速度确实不丝滑。我想要的快捷输入和小界面,就像你说的集中应对。不过我是个设计师,所以可能对界面美观度要求更高一点。我找过一些软件,比如 nvALT ; FSnotes ;打开速度都很快,只是一些细节,样式不太好,所以我只拿来记录一些摘抄。你可以试一试,后者基于前者开发
Oz37sW2w3MIZf56o
2023-06-17 22:58:07 +08:00
歪个楼,求一个可以上 ChatGPT 不封号的梯子
temberature
2023-06-18 16:32:35 +08:00
@chenyduan 最近好多了,网络一般只是不让用,疯号好多是因为黑卡
temberature
2023-06-18 16:37:09 +08:00
@llsongll 感谢推荐,其实我在开发一个 IM 架构的给自己用,就是好奇为什么你也有这种需求,样式我喜欢简洁的那种,一般都不会太丑。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/947094

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX