插件开发求助丨安卓端如何通过本地 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();
    }
}

  • 思源笔记

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

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

    22704 引用 • 91154 回帖
  • Q&A

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

    8283 引用 • 37779 回帖 • 158 关注
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 动态替换,确实是目前能想到的一个方案了

  • 88250

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

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

    1 回复
  • 88250

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

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

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

    1 回复
  • 88250

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

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

    2 回复
  • 88250

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

  • 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 更新了该回帖
  • 88250

    要用 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 回复
  • 88250

    看上去这个设计还可以,颜色那些后面再调整。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 回复
  • 88250

    应该可以的,但最好还是搭建一下开发环境实际编译看看。

    3 回复
  • Achuan-2

    好滴,我在搭建了

  • Achuan-2 2

    hhhh ,可以的

    PixPin20241027164330.png

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

推荐标签 标签

  • 笔记

    好记性不如烂笔头。

    308 引用 • 793 回帖
  • Telegram

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

    5 引用 • 35 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    134 引用 • 190 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2388 回帖
  • sts
    2 引用 • 2 回帖 • 195 关注
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    2 引用 • 14 回帖
  • Vditor

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

    354 引用 • 1821 回帖 • 1 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    132 引用 • 1114 回帖 • 127 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖 • 3 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 135 关注
  • 招聘

    哪里都缺人,哪里都不缺人。

    190 引用 • 1057 回帖 • 1 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 141 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 137 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 636 关注
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 170 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    85 引用 • 139 回帖 • 1 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 4 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 485 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 766 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖 • 10 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    91 引用 • 751 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    266 引用 • 666 回帖
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 3 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 64 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 6 关注