【ChatGPT with Date】使用 ChatGPT 时显示消息时间的插件

文章目录

    • [1. 介绍](#1. 介绍)
    • [2. 使用方法](#2. 使用方法)
      • [2.1 安装 Tampermonkey](#2.1 安装 Tampermonkey)
      • [2.2 安装脚本](#2.2 安装脚本)
      • [2.3 使用](#2.3 使用)
    • [3. 配置](#3. 配置)
      • [3.1 时间格式](#3.1 时间格式)
      • [3.2 时间位置](#3.2 时间位置)
    • [4. 反馈](#4. 反馈)
    • [5. 未来计划](#5. 未来计划)
    • [6. 开源协议](#6. 开源协议)
    • [7. 供给开发者自定义修改脚本的文档](#7. 供给开发者自定义修改脚本的文档)
      • [7.1 项目组织架构](#7.1 项目组织架构)
      • [7.2 定义新的 Component](#7.2 定义新的 Component)
        • [(1) 定义一个新的 Component 类](#(1) 定义一个新的 Component 类)
        • [(2) 注册该 Component](#(2) 注册该 Component)
      • [7.3 一些建议](#7.3 一些建议)
        • [(1) 注入外部 JavaScript 库](#(1) 注入外部 JavaScript 库)
    • [X. Changelog](#X. Changelog)

1. 介绍

有时我们希望看到 ChatGPT 的消息时间,但 ChatGPT 并没有显示消息时间的功能。

本项目通过 Tampermonkey 开发,可以在 Chrome 和 Firefox 等支持 Tampermonkey 插件的浏览器上使用,实现显示 ChatGPT每一条消息时间的功能。

该插件不但可以获取以往的消息时间,还可以实时获取新消息的时间。

提供多种配置选项,例如时间显示格式、时间显示位置等。

除此之外,时间样式高度自定义,你可以输入以下 html

代码来实现上图的效果。具体的时间格式化规则请参考 [3.1 时间格式](#3.1 时间格式)

html 复制代码
<span style="border-radius: 8px; color: #E0E0E0; font-size: 0.9em; overflow: hidden; display: inline-block;"><span
        style="background: #333; padding: 2px 4px 2px 10px; display: inline-block;">{yyyy}-{MM}-{dd}</span><span
        style="background: #606060; padding: 2px 10px 2px 4px; display: inline-block;">{HH}:{mm}:{ss}</span></span>

2. 使用方法

2.1 安装 Tampermonkey

可查看 Tampermonkey 首页 查看详细的使用方法。

2.2 安装脚本

访问链接: Greasy Fork - ChatGPT with Date,点击 安装此脚本 安装脚本。

2.3 使用

首次使用请允许跨源资源共享(CORS)请求,本项目将请求 Vue.js 和 NaiveUI 的资源,以便生成配置面板。

打开 ChatGPT 页面,即可看到消息时间。你可以在此处打开配置面板。

3. 配置

3.1 时间格式

默认支持的时间格式有(文章平台不同可能无法正常显示):

模板 样例
<span>{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}</span> 2000-12-31 00:00:00
<span>{MM}/{dd}/{yyyy} {HH}:{mm}:{ss}</span> 12/31/2000 00:00:00
<span>{MM}-{dd} {HH}:{mm}:{ss}</span> 12-31 00:00:00
<span>{MM}-{dd} {HH}:{mm}</span> 12-31 00:00
<span>{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}.{ms}</span> 2000-12-31 00:00:00.000
<span style="background: #2B2B2B;border-radius: 8px;padding: 1px 10px;color: #717171;">{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}</span> 2000-12-31 00:00:00
<span style="border-radius: 8px; color: #E0E0E0; font-size: 0.9em; overflow: hidden; display: inline-block;"><span style="background: #333; padding: 2px 4px 2px 10px; display: inline-block;">{yyyy}-{MM}-{dd}</span><span style="background: #606060; padding: 2px 10px 2px 4px; display: inline-block;">{HH}:{mm}:{ss}</span></span> 2000-12-1300:00:00

支持的时间元素有:

  • {yyyy}: 年份
  • {MM}: 月份
  • {dd}: 日期
  • {HH}: 小时
  • {mm}: 分钟
  • {ss}: 秒
  • {ms}: 毫秒

你完全可以自定义时间格式,只需要输入你想要的 html 代码即可,脚本将替换上面的模板时间元素为当前时间的相应数据。

在介绍中已经给出了一个示例:

html 复制代码
<span style="border-radius: 8px; color: #E0E0E0; font-size: 0.9em; overflow: hidden; display: inline-block;"><span
        style="background: #333; padding: 2px 4px 2px 10px; display: inline-block;">{yyyy}-{MM}-{dd}</span><span
        style="background: #606060; padding: 2px 10px 2px 4px; display: inline-block;">{HH}:{mm}:{ss}</span></span>

3.2 时间位置

时间位置有三种选择:

  • 角色之后(靠左): 时间显示在角色名字的后面,并靠左显示。
  • 角色之后(靠右): 时间显示在角色名字的后面,并靠右显示。
  • 角色之下: 时间显示在角色名字下方。

4. 反馈

如果你有任何问题或建议,欢迎在 GitHub Issues脚本反馈区 中提出。

5. 未来计划

  • 国际化:脚本支持多种语言(日志、提示等)。
  • 时间格式化细粒度配置面板:优化时间格式自定义功能,而不是难以维护的 HTML字符串 表示。
  • 时间格式化元素:支持更多的时间格式化元素,例如星期、月份(英文)等。
  • 时间格式化规则:支持更多的时间格式化规则,例如 12 小时制、24 小时制等。

6. 开源协议

本项目遵循 MIT 开源协议。

CopyRight © 2024~Present Jiang Liu

7. 供给开发者自定义修改脚本的文档

7.1 项目组织架构

本项目采用依赖注入(DI)的方式组织各个 Component,主要包括以下几个部分:

  • UserConfig: 用户配置信息,包括时间格式、时间位置等。
  • StyleService: 样式服务,负责跟踪管理一些可变化的样式。
  • MessageService: 消息服务,负责管理和存储消息信息。
  • MonitorService: 监控服务,负责劫持 Fetch 请求和实时监听页面新消息的添加。
  • TimeRendererService: 时间渲染服务,负责渲染时间。
  • ConfigPanelService: 配置面板服务,负责生成基于 Vue+NaiveUI 的配置面板。

上述服务之间的依赖关系如下:
UserConfig StyleService MessageService MonitorService TimeRendererService ConfigPanelService

本项目采用的依赖注入方式限制了循环依赖的发生,依赖注入的设计架构允许组件保持独立于其依赖项的具体实现。这种技术可以使代码更容易理解、维护和测试。

之所以要避免循环依赖,因为循环依赖违反了单一职责原则、依赖倒置原则。

7.2 定义新的 Component

如果你想自定义一个新的 Component,你需要:

(1) 定义一个新的 Component 类
  • 继承:该类必须继承自 Component
  • 构造函数:在构造函数中定义 dependencies 属性,该属性是一个数组,数组中的每个元素是一个对象,对象包含两个属性:field
    clazz,分别表示依赖的字段名和依赖的类。
  • 依赖注入:不应该在构造函数中进行除了定义依赖关系之外的其他操作,因为依赖关系的注入是在 Component::initDependencies
    方法中进行的。在该方法执行之前,依赖关系是无法使用的。
  • 初始化函数:在 init 方法中进行正式的初始化操作,在该方法中可以使用依赖注入的属性。
  • 依赖关系:应当避免循环依赖,否则会导致初始化失败。
javascript 复制代码
class NewComponent extends Component {
    constructor() {
        super();
        this.userConfig = null
        this.timeRendererService = null
        this.messageService = null
        this.dependencies = [
            {field: 'userConfig', clazz: UserConfig},
            {field: 'timeRendererService', clazz: TimeRendererService},
            {field: 'messageService', clazz: MessageService},
        ]
    }

    init() {
        // 正式初始化
    }
}
(2) 注册该 Component

将你的 Component 注册到 Main.ComponentsConfig 中,不必担心注册的顺序,因为 Main 类会自动按照依赖关系的顺序进行初始化。

javascript 复制代码
class Main {
    static ComponentsConfig = [
        UserConfig, StyleService, MessageService,
        MonitorService, TimeRendererService, ConfigPanelService,
        NewComponent,
    ]
}

于是新的依赖关系图如下所示:
UserConfig StyleService MessageService MonitorService TimeRendererService ConfigPanelService NewComponent

7.3 一些建议

(1) 注入外部 JavaScript 库

请使用 GM_xmlhttpRequest 来获取外部 JavaScript 库的内容,再以字符串的形式注入到页面中。

如果你直接在页面中引入外部 JavaScript 库,可能有CSP限制。

下面是在项目中注入 Vue.js 和 NaiveUI 的示例:

javascript 复制代码
function loadScript() {
    return new Promise(resolve => {
        // ✅✅ 以下方法没有 CSP 限制
        let completeCount = 0;
        const addScript = (content) => {
            let script = document.createElement('script');
            script.textContent = content;
            document.body.appendChild(script);
            completeCount++;
            if (completeCount === 2) {
                resolve()
            }
        }
        GM_xmlhttpRequest({
            method: "GET", url: "https://unpkg.com/vue@3.4.26/dist/vue.global.js", onload: function (response) {
                addScript(response.responseText);
            }
        });
        GM_xmlhttpRequest({
            method: "GET", url: "https://unpkg.com/naive-ui@2.38.1/dist/index.js", onload: function (response) {
                addScript(response.responseText);
            }
        });
        // ❎❎ 以下方法有 CSP 限制
        // const naiveScript = document.createElement('script');
        // naiveScript.setAttribute("type", "text/javascript");
        // naiveScript.text = "https://unpkg.com/naive-ui@2.38.1/dist/index.js";
        // document.documentElement.appendChild(naiveScript);
    })
}

X. Changelog

markdown 复制代码
- v1.1.0 - 2024-05-02 17:50:04
    - 添加更多时间格式的模板
相关推荐
曼城周杰伦8 分钟前
自然语言处理:第六十三章 阿里Qwen2 & 2.5系列
人工智能·阿里云·语言模型·自然语言处理·chatgpt·nlp·gpt-3
狸克先生8 小时前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
新加坡内哥谈技术11 小时前
Mistral推出“Le Chat”,对标ChatGPT
人工智能·chatgpt
nbsaas-boot12 小时前
如何利用ChatGPT加速开发与学习:以BPMN编辑器为例
学习·chatgpt·编辑器
hunteritself1 天前
ChatGPT高级语音模式正在向Web网页端推出!
人工智能·gpt·chatgpt·openai·语音识别
Doker 多克1 天前
Spring AI 框架使用的核心概念
人工智能·spring·chatgpt
吴边落木1 天前
如何滚动截屏长图?手把手教你
插件
曼城周杰伦1 天前
自然语言处理:第六十二章 KAG 超越GraphRAG的图谱框架
人工智能·pytorch·神经网络·自然语言处理·chatgpt·nlp·gpt-3
爱技术的小伙子2 天前
【ChatGPT】ChatGPT在多领域知识整合中的应用
chatgpt
学习前端的小z2 天前
【AIGC】如何准确引导ChatGPT,实现精细化GPTs指令生成
人工智能·gpt·chatgpt·aigc