插件开发求助丨安卓端如何通过本地 URL 返回动态 svg

20241027 更新

经 D 大指导,给思源笔记添加了一个 api,/api/icon/getDynamicIcon,可以通过 api/icon/getDynamicIcon?color=red&lang=zh_CN&date=2024-10-27 直接调用动态图标

✨ Add internal kernel API `/api/icon` by Achuan-2 · Pull Request #12939 · siyuan-note/siyuan


需求

想参考 wolai 的动态图标:https://www.wolai.com/wolai/2tkzTE5w7invgSTqKjSwL7

在思源也开发一个动态图标插件,目的是可以直接本地生成动态图标,而不依赖网络(wolai 说不准哪天就不让非会员用这个功能了)

目前已经在 windows 端,基本上把 wolai 的动态图标都抄了一遍,具体见插件开发 idea 丨模仿 wolai 的动态日历图标 - 链滴

PixPin20241026172628.png

问题

但是目前的问题是,我在安卓上没法用,安卓不方便调试,不知道出了什么问题

我采取的方案是参考插件 taotaochen86/siyuan-plugin-jsrunner,是写了一个 http 服务器,想问问大佬们有什么办法,能解决这个问题,让各端都可以使用链接来返回动态 svg。

下面是我目前的插件代码

server.ts

const http = globalThis.require("http");
// src/server.ts


interface ColorScheme {
    primary: string;
    secondary: string;
}

export class CalendarServer {
    private server: any;
    private port: number;
    private colorSchemes: { [key: string]: ColorScheme } = {
        red: { primary: "#cf5659", secondary: "#f3aab9" },
        blue: { primary: "#5AA9E6", secondary: "#3A79B6" },
        yellow: { primary: "#DBAD6A", secondary: "#AB7D3A" },
        green: { primary: "#5FBB97", secondary: "#2F8867" },
        purple: { primary: "#E099FF", secondary: "#BE66CF" },
        pink: { primary: "#EA5D97", secondary: "#CA3D77" },
        fuchsia: { primary: "#93627F", secondary: "#633241" },
        grey: { primary: "#565557", secondary: "#767577" }
    };

    constructor(port: number) {
        this.port = port;
    }

    public start(): void {
        if (!this.server) {
            this.server = http.createServer((req: any, res: any) => {
                const url = new URL(req.url, `http://localhost:${this.port}`);
                const params = {
                    color: url.searchParams.get('color') || 'red',
                    date: url.searchParams.get('date'),
                    locale: url.searchParams.get('locale') || 'cn',
                    type: url.searchParams.get('type') || '1'
                };

                const svg = this.generateCalendarSVG(params);
                res.writeHead(200, {
                    'Content-Type': 'image/svg+xml',
                    'Cache-Control': 'no-cache',
                    'Pragma': 'no-cache'
                });
                res.end(svg);
            });

            this.server.listen(this.port);
            console.log(`Calendar SVG server started on port ${this.port}`);
        }
    }

    public stop(): void {
        if (this.server) {
            this.server.close();
            this.server = null;
            console.log(`Calendar SVG server stopped`);
        }
    }

index.ts

import { Plugin } from "siyuan";
import "./index.scss";
import { CalendarServer } from "./server";

export default class CalendarSVGPlugin extends Plugin {
    private server: CalendarServer = new CalendarServer(45678);

    onload() {

        // 启动服务器
        this.server.start();
    }

    onunload() {
        // 关闭服务器
        this.server.stop();
    }
}

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    22363 引用 • 89491 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8124 引用 • 37039 回帖 • 159 关注
4 操作
Achuan-2 在 2024-11-08 09:34:31 更新了该帖
Achuan-2 在 2024-10-28 00:38:05 更新了该帖
Achuan-2 在 2024-10-27 00:55:35 更新了该帖
Achuan-2 在 2024-10-26 17:47:21 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 没看明白为什么一定要启用 Server。是因为用图片加载的,所以需要服务端返回资源?

    1 回复
  • Achuan-2

    只要能根据参数动态返回 svg 就行,因为比如当天日历图标和倒数日就需要每天更新

    wolai 是用 api 实现的

    1 回复
  • 你要行内的,还是只要显示出来就行?

    1 回复
  • Achuan-2

    需要行内的,可以用图片链接语法显示,之后如果思源支持文档图标用链接,就可以用动态图标了

  • 你要用 api 方式就要用 server 服务返回,这样的话除非有服务器支持,如果没有的话,移动端实现较为麻烦。

    建议使用 HTML 实现或自己写个插件动态插入这种图标。

    HTML 实现的思路就是,在思源里用 HTML 嵌入,然后允许 HTML 块内执行脚本后,也可以用 js 动态生成数据(HTML 块内脚本目前思源 3.1.10 有 bug,issue: Issue #12921 · siyuan-note/siyuan

    image.png

    自己写插件的思路,就是通过 js 把 svg 动态生成图片(问问 ai 就知道了),然后再把图片插入到思源中,如果图片插入后不实时更新就不需要加载时重新生成,如果需要实时更新,需要加载时实时生成。

    1 回复
    1 操作
    wilsons 在 2024-10-26 21:16:09 更新了该回帖
  • 用 server 是不行的,对于安卓和 docker 运行的这些,因为他们没有 electron 运行时,我建议你直接用插件 js 监听具有指定你这个 url 的元素,然后动态修改 dom

    1 回复
  • Achuan-2

    谢谢,原来安卓没有 electron runtime。

    可能得类似你在思源渲染 tif 的方案,动态替换

    不过这样有点麻烦了,我再想想

  • Achuan-2

    我其实之前已经写了一个倒数日挂件块了

    wolai 动态图标,也用挂件的方式写了个 demo

    之所以想用 url 返回 svg,是考虑思源万一支持在线的文档图标的话,就可以使用

    js 动态替换,确实是目前能想到的一个方案了

  • 我觉得比较好的方案还是内核内置生成动态图标,看看谁帮忙 PR 贡献一下吧。

    2 回复
  • 内置的话应该没法随便改吧

    1 回复
  • 我的意思是和 wolai 一样,支持动态图标特性。

    1 回复
  • 刚刚看了一下,感觉这个动态图标不容易搞国际化,要做的话只能先支持中文和英文。

    不过最简单的方法还是支持图片用链接,用户直接用 Wolai 的图标就行了。

    1 回复
  • 我理解只需要改变 svg 中的一些文本值就可以国际化了,内核动态生成 svg 代码。

    1 回复
  • 我想到的是各个语种的词汇长度不一致,感觉直接替换文本的话弄出来会不太好看

    2 回复
  • 先确定机制的可行性,是否美观最后可以取舍,比如中英文缩写肯定可行,其他某些语言可能也行。

  • Achuan-2

    生成动态图标逻辑我基本已经写好了,把 wolai 的 9 种样式都 copy 了(没有 type2,因为 wolai type1 和 type2 貌似就是一样的),也加了中英文切换(通过 locale=cn,locale=en 切换)

    但是不知道内核内置这个功能怎么加,是需要用 go 写吗

    调用也是调 api 的形式生成 svg 吗

    如果官方要集成这个功能,直接用 wolai 的样式会有侵权风险吗,是不是得修改下,wolai 本身的设计是真的好看,我目前只对 type6 倒数日图标进行了修改,添加了天/days 的文字显示

    1 回复
    4 操作
    Achuan-2 在 2024-10-27 00:54:21 更新了该回帖
    Achuan-2 在 2024-10-27 00:52:27 更新了该回帖
    Achuan-2 在 2024-10-27 00:50:10 更新了该回帖
    Achuan-2 在 2024-10-27 00:49:14 更新了该回帖
  • 要用 go 并且得重新实现避免侵权

    3 回复
  • Achuan-2

    svg 可以直接指定字体类别和字体大小的,国际化肯定没问题,就是麻烦,月份和星期的英文是通用的,感觉没太必要纠结国际化,年份和日期就用阿拉伯数字

    1 操作
    Achuan-2 在 2024-10-27 01:17:23 更新了该回帖
  • Achuan-2 1

    重新设计好办,我可以用 adobe illustrator 设计,导出 svg,然后参考 wolai,替换文本和支持修改配色

    这个我可以帮忙搞

    不过内核我估计就得靠其他大佬贡献了

  • Achuan-2

    D 大看看这种程度上的修改可以不
    参考 2018 年 Terence Eden 开源的动态日历图标:edent/Dynamic-SVG-Calendar-Icon: Here it is, an SVG calendar which always display's today's date.(wolai 的动态日历图标是 2020.09.04 才出的,见 wolai 2020.9 更新

    Terence Eden 的

    image.png

    修改:

    • 把孔洞补上
    • 英文和数字字体改为 Arial
    • 灰色背景调亮

    image.png

    添加年份(wolai 没有同时显示年月日星期的图标)

    image.png

    wolai 的

    image.png

    1 操作
    Achuan-2 在 2024-10-27 09:34:33 更新了该回帖
  • Achuan-2

    另外 go 实现,如果 D 大可以告诉我在哪个 go 文件搞,参考哪个函数实现,我可以试试

    内核可以实现 http://127.0.0.1:6806/api/icon?type=1 这种方式渲染 svg,还是其他什么方式呢

    1 回复
  • 看上去这个设计还可以,颜色那些后面再调整。go 的话请求路由配置在 router.go 里面,你可以参考一下其他接口的写法。

    2 回复
  • Achuan-2 2

    设计完成了,设计了 8 种 type,8 种配色

    源码见:Achuan-2/siyuan-plugin-dynamic-calendar-icon: 思源笔记动态图片设计

    内核我晚点再折腾

    参数

    • type:图标类型,默认为 1

      1. type=1:显示年月日星期
      2. type=2 显示年月日
      3. type=3 仅显示年月
      4. type=4 仅显示年
      5. type=5 当前周数
      6. type=6:仅返回星期
      7. type=7:倒数日
      8. type=8:汉字字母数字图标
    • locale:中英文切换,默认为 cn,仅在 type=1、2、3、5、6、7 时有效

      • locale=cn:显示中文
      • locale=en:显示英文
    • color:设置配色,一共八种配色

      • color=red
      • color=blue
      • color=yellow
      • color=green
      • color=purple
      • color=pink
      • color=orange
      • color=grey

      PixPin20241027141500.png

    • date: 设置日期,默认为当前日期,日期设置格式为 yyyy-mm-dd,仅在 type=1-6 时有效

    • content:设置文字图标的内容,默认为空,仅在 type=8 时有效

    示例

    type=1:显示年月日星期

    默认显示今天的日期。

    可通过 date=2024-10-26 指定显示的日期PixPin20241027141546.png

    type=2:显示年月日

    PixPin20241027141656.png

    type=3:仅显示年月

    PixPin20241027141746.png

    type=4:仅显示年

    PixPin20241027141804.png

    type=5:当前周数

    PixPin20241027141813.png

    type=6:仅返回星期

    不输入 color 的话,默认星期一到星期五为红色,星期六和星期日为蓝色
    PixPin20241027141827.png

    指定 color
    PixPin20241027141953.png

    type=7:倒数日

    该图标会显示当前日期与指定日期之间的天数。

    支持 locale=en 修改为英文:

    • 已过 用 Past 表示。
    • 还有 用 Left 表示。

    PixPin20241027142004.png

    PixPin20241027142021.png

    PixPin20241027142030.png

    type=8:文字图标

    该图标可以显示一个指定的汉字、字母、数字组合。

    PixPin20241027142038.png

    2 操作
    Achuan-2 在 2024-10-27 15:52:29 更新了该回帖
    Achuan-2 在 2024-10-27 14:31:55 更新了该回帖
  • Achuan-2

    打算试试了,尝试之前,想问问 api 支持这样调用吗

    http://127.0.0.1:6806/api/system/dynamicIcon?type=1&color=blue&date=2023-05-20&locale=en

    ai 给的代码, 这样就能获取 URL 里的 type 了吗

    func getDynamicIcon(c *gin.Context) {
        iconType := c.Query("type")
      
        var svgContent string
        switch iconType {
        case "1":
            // 这里是一个简单的SVG图标示例
            svgContent = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
                <circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2"/>
                <path d="M12 8v8M8 12h8" stroke="currentColor" stroke-width="2"/>
            </svg>`
        default:
            c.String(400, "Invalid icon type")
            return
        }
      
        // 设置响应头
        c.Header("Content-Type", "image/svg+xml")
        c.String(200, svgContent)
    }
    
    
    1 回复
  • 应该可以的,但最好还是搭建一下开发环境实际编译看看。

    3 回复
  • Achuan-2

    好滴,我在搭建了

  • Achuan-2 2

    hhhh ,可以的

    PixPin20241027164330.png

请输入回帖内容 ...
Achuan-2
给时间以生命而不是给生命以时间,如果你喜欢我的分享,欢迎给我买杯咖啡 https://www.yuque.com/achuan-2 上海

推荐标签 标签

  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    20 引用 • 7 回帖
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    222 引用 • 473 回帖
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 211 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖 • 1 关注
  • C

    C 语言是一门通用计算机编程语言,应用广泛。C 语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。

    85 引用 • 165 回帖 • 3 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    110 引用 • 54 回帖
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    153 引用 • 3783 回帖 • 1 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖 • 3 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 212 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    568 引用 • 3532 回帖 • 1 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 364 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    6 引用 • 15 回帖 • 114 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 552 关注
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    944 引用 • 943 回帖 • 1 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 589 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 85 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 633 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    352 引用 • 1815 回帖
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 339 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    123 引用 • 74 回帖
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 43 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    407 引用 • 1246 回帖 • 582 关注
  • 电影

    这是一个不能说的秘密。

    120 引用 • 599 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖