GithubHelp home page GithubHelp logo

tanknee / memocast Goto Github PK

View Code? Open in Web Editor NEW
359.0 10.0 32.0 53.16 MB

Yet another elegant Wiz Note Client, which was built with Quasar UI Framework and based on Electron.

Home Page: https://tanknee.github.io/Memocast

License: MIT License

JavaScript 79.33% HTML 0.23% Vue 12.86% Sass 0.07% CSS 7.51%
vue electron editor markdown wiznote neeto-vue wiz-community quasar-framework memocast github

memocast's Introduction

AppIcon

Memocast

GitHub Workflow Status (branch) GitHub Releases GitHub All Releases GitHub Release Date GitHub repo size GitHub

Introduction

一款基于 Electron 、Muya 、Monaco 和为知笔记的编辑器,实现了类似 Typora 的编辑体验,并添加了更优秀的源代码模式,更好的图片服务,支持为知笔记私有部署,提供了众多快捷键。

Memocast - an awesome wiznote client, online note. | Product Hunt

Download

你可以在 GitHub 的 Release 页面下载最新版本,与此同时,你也可以使用内置的更新按钮获取最新版本,注意 mac 并不支持直接使用内置更新,因为受限于 macOS 的安全策略,所有自动安装的应用应该被有效地签名。

GitHub Release:Releases · TankNee/Memocast · GitHub

Arch Linux

通过 AUR 安装 Memocast

# AUR helper
# yay
yay -S memocast-bin
# pikaur
pikaur -S memocast

我没有测试过上述命令,如果有误请帮我指正。感谢 yjun123 的帮助。

Documentation

你可以在 Memocast 的文档中找到与软件相关的实用用法与介绍。

文档地址:https://www.tanknee.cn/Memocast/

Feature

  1. 较为完整的为知服务的支持。

    1. 笔记增删查改

    2. 文件夹增删

    3. 笔记导出成 PNG、Markdown

    4. 笔记文件夹批量导出 Markdown

    5. 支持为知图片服务

    6. 笔记标签增删查改

    7. 私有化部署服务器的支持

  2. 良好的 Markdown 编辑器体验

    1. 按下 @ 快捷输入

    2. 完整的快捷键支持,并在 macOS 下支持菜单和帮助查询。

    3. 将为知的网页剪辑笔记轻松转换为可阅读的 Markdown 文件

    4. 良好的图片支持,支持为知图片,支持 PicGo 上传图片,支持本地图片

    5. 相比 marktext ,编辑器做了很多的优化和本地化

    6. 支持笔记目录,支持目录跳转

    7. 支持流程图,vega 图,mermaid 图等等

    8. 笔记锁定模式,锁定之后键盘无法输入,减少误触

    9. 所见即所得,良好输入体验

    10. 支持 PicGo 图片服务,将笔记图片上传到指定图床

    11. 支持使用 pangu 格式化 markdown 文本,自动在中英文字符之间加入空格

      你好Memocast => 你好 Memocast
      
  3. 强大的源代码模式

    1. 使用 Monaco 作为源代码编辑器

    2. 使用 CmdOrCtrl + Shift + . 快捷切换源代码模式和 markdown 模式

    3. 语法高亮

    4. 侧边栏预览

  4. 完整开源, 项目 All in Github, 在网络畅通的情况下可以使用内置的自动更新,快速将软件更新到最新版。

Screenshot

主界面

编辑器

快捷输入

源代码模式

编辑器与国际化

图片快速插入

编辑器快捷操作

切换源代码模式

打字机模式

更多特色功能还请下载之后体验

Reference

感谢 Quasar Framework、Monaco 以及 MarkText 项目,从他们身上学到了很多,Memocast 有很多的灵感都来自他们,笔记的所见即所得编辑器来自 MarkText 中的 Muya 编辑器,源代码模式使用的编辑器来自 Monaca-Editor 项目。

感谢 Quasar 中文网,他们的文档对我有很大帮助。http://www.quasarchs.com/

Sponsor

https://github.com/lifeend

Contributor

感谢所有Memocast和Neeto-Vue的贡献者!

Thanks to all Memocast's contributors as well as Neeto-Vue's contributors!

Community

关注为知社区订阅号,获取最新信息:

qrcode_for_gh_wizcommunity

如果你愿意促进社区发展,那加入我们吧!

License

Copyright © 2021 TankNee.
This project is MIT licensed.

FOSSA Status

memocast's People

Contributors

akashi2333 avatar altairwei avatar anastasiawangyx avatar dependabot[bot] avatar fossabot avatar tanknee avatar yjun123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

memocast's Issues

显示密码

我劝老泥巴不要不识好歹,赶紧把显示密码功能加上

默认全展开 markdown 内容的标题层级树

在编辑或者阅读时使用标题层级树的目的主要是快速定位。当文章内容很长,标题层级树也比较深时,全展开具有优势,因为用眼睛和滑轮浏览标题层级树比用鼠标一个个展开不同的层级要快很多。

添加markdown批量导出功能

为知笔记的markdown是用html存储的,不是很通用,也不方便迁移,希望能增加批量导出markdown格式的功能

为什么关闭后还有多个进程在后台?

感谢开发了这么好的软件,有两点建议希望采纳 ;-)
1.作为笔记软件,建议点击右上角关闭按钮后可以选择是最小化到托盘,而不是关闭
2.为什么点击右上角关闭按钮后,进程中还有好几个Neeto-Vue进程?

感谢

编辑器在光标落到其它markdown语法标志符时,可以显示带标志符的markdown源码,但是标题不会。建议改成同样显示源码,加减#个数就可以调整标题等级。

非常感谢你开发了Memocast,即时同窗渲染是一个让我重新使用为知笔记账号的功能。

顺便提一下,我是同时发现的Memocast和Wiznote lite,最初选择了使用Wiznote lite,因为它启动感觉比较快,而且编辑器支持本issue中提到的光标移到标题进显示标题的源码。但是用了一段时间后发现Wiznote lite渲染器对mermaid图的支持不好,页面布局占用很大,感觉只是把代码隐藏了,但空间仍然保留着,而且配色很差,有时候背景色与字体颜色几乎一样,看不清字体。而memocast的vditor渲染得要好多了,显示效果完美。但是Memocsst也有种种不足,比如没有移动客户端、不支持wiznote lite的tag标志,启动慢等等。

两个前端都在发展的早期,还存在各种不足,希望能发展得越来越好!所以我提了一系列建议,从用户的角度提供一点反馈供优化时参考。再次感谢开发了这么好的笔记前端让我们使用。

导出功能建议

  • 导出md文件,图片转换为base64,这样换到其他工具依然可以用。
  • 希望增加pdf的导出

能否自定义字体?

无法同步

无法创建笔记、文件夹,也无法同步

笔记中的图片时常会有load image failed提示。

但是图片确实在服务器上保存成功的。网页版为知笔记和winote lite客户端能正常显示。这个问题为知笔记客户端比较少见,wiznote lite也时常发生。建议添加一个重新载入的功能,让用户在遇到问题时能有办法应对,以提升用户体验。

文件夹手动排序功能的实现思路

首先 WizQTClient 的实现方式可以参考一下:

void WizCategoryView::updatePersonalFolderLocation(WizDatabase& db, \
                                                    const QString& strOldLocation, const QString& strNewLocation)
{
    WizCategoryViewAllFoldersItem* pItem = dynamic_cast<WizCategoryViewAllFoldersItem* >(findAllFolderItem());
    if (!pItem)
        return;

    // the last item of folder root should be trash
    WizCategoryViewTrashItem* trashItem = findTrash(db.kbGUID());
    if (trashItem && pItem->indexOfChild(trashItem) != pItem->childCount() - 1)
    {
        pItem->takeChild(pItem->indexOfChild(trashItem));
        pItem->insertChild(pItem->childCount(), trashItem);
    }

    if (strOldLocation != strNewLocation)
    {
        db.updateLocation(strOldLocation, strNewLocation);
        CWizStdStringArray childLocations;
        db.getAllChildLocations(strNewLocation, childLocations);
        for (CString childLocation : childLocations)
        {
            findFolder(childLocation, true, true);
        }
    }

    // 文件夹移动后触发folder loacation changed,需要更新顺序
    QString str = getAllFoldersPosition();
    db.setFoldersPos(str, -1);
    db.setFoldersPosModified();

    emit categoryItemPositionChanged(db.kbGUID());
}

QString WizCategoryView::getAllFoldersPosition(WizCategoryViewFolderItem* pItem, int& nStartPos)
{
    if (!pItem)
        return QString();

    QString str ="\"" + pItem->location() + "\": " + QString::number(nStartPos);
    nStartPos ++;

    for (int i = 0; i < pItem->childCount(); i++)
    {
        WizCategoryViewFolderItem* childItem = dynamic_cast<WizCategoryViewFolderItem* >(pItem->child(i));
        Q_ASSERT(childItem);
        str += ", \n";
        str += getAllFoldersPosition(childItem, nStartPos);
    }

    return str;
}

void WizDatabase::setFoldersPos(const QString& foldersPos, qint64 nVersion)
{
    setLocalValueVersion("folders_pos", nVersion);
    setMeta("SYNC_INFO", "FOLDERS_POS", foldersPos);

    bool bPositionChanged = false;

    CString str(foldersPos);
    str.trim();
    str.trim('{');
    str.trim('}');
    str.replace("\n", "");
    str.replace("\r", "");
    if (str.isEmpty())
        return;

    CWizStdStringArray arrPos;
    ::WizSplitTextToArray(str, ',', arrPos);

    QSettings* setting = WizGlobal::settings();
    setting->beginGroup("FolderPosition");
    setting->remove("");
    setting->endGroup();

    CWizStdStringArray::const_iterator it;
    for (it= arrPos.begin(); it != arrPos.end(); it++) {
        CString strLine = *it;
        CString strLocation;
        CString strPos;
        if (!::WizStringSimpleSplit(strLine, ':', strLocation, strPos))
            continue;
        strLocation.trim();
        strLocation.trim('\"');

        int nPos = wiz_ttoi(strPos);
        if (0 == nPos)
            continue;

        int nPosOld = setting->value("FolderPosition/" + strLocation).toInt();
        if (nPosOld != nPos) {
            setting->setValue("FolderPosition/" + strLocation, nPos);
            bPositionChanged = true;
        }
    }

    setting->sync();

    if (bPositionChanged) {
        Q_EMIT folderPositionChanged();
    }
}

void WizDatabase::setFoldersPosModified()
{
    setLocalValueVersion("folders_pos", -1);
    setLocalValueVersion("folders", -1);
}

void WizDatabase::setLocalValueVersion(const QString& strKey,
                                        qint64 nServerVersion)
{
    setMetaInt64(WIZ_META_SYNCINFO_SECTION, "KEY_" + strKey + "_VERSION", nServerVersion);
}

然后 API 文档中写了:

# 文件夹排序
put /ks/category/sort/:kbGuid
body: {

  '/My Notes/': 0,
  '/New Folder/': 1,
}

# 一个关于图片的严重问题

我没有处理好关于Resources的展示方式,所以在保存的时候会更改笔记的内容,导致图片可能会过期?虽然我暂时没有遇到,但存在这种风险,这个问题将在下个版本修复

本地化为知笔记定义好的文件夹

首先查看 WizQTClient 源代码可以发现:

bool WizIsPredefinedLocation(const QString& strLocation)
{
    if (strLocation == "/Deleted Items/") {
        return true;
    }else if (strLocation == "/My Notes/") {
        return true;
    } else if (strLocation == "/My Journals/") {
        return true;
    } else if (strLocation == "/My Contacts/") {
        return true;
    } else if (strLocation == "/My Events/") {
        return true;
    } else if (strLocation == "/My Sticky Notes/") {
        return true;
    } else if (strLocation == "/My Emails/") {
        return true;
    } else if (strLocation == "/My Drafts/") {
        return true;
    } else if (strLocation == "/My Tasks/") {
        return true;
    } else if (strLocation == "/My Tasks/Inbox/") {
        return true;
    } else if (strLocation == "/My Tasks/Completed/") {
        return true;
    }

    return false;
}

然后简体翻译是这样的:

    <message>
        <location filename="../src/share/WizMisc.cpp" line="351"/>
        <source>/Deleted Items/</source>
        <translation>/回收站/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="355"/>
        <source>/My Notes/</source>
        <translation>/我的笔记/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="359"/>
        <source>/My Journals/</source>
        <translation>/我的日记/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="363"/>
        <source>/My Contacts/</source>
        <translation>/我的联系人/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="367"/>
        <source>/My Events/</source>
        <translation>/我的事件/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="371"/>
        <source>/My Sticky Notes/</source>
        <translation>/我的桌面便笺/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="375"/>
        <source>/My Emails/</source>
        <translation>/我的邮件/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="379"/>
        <source>/My Drafts/</source>
        <translation>/我的草稿/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="383"/>
        <source>/My Tasks/</source>
        <translation>/我的任务/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="387"/>
        <source>/My Tasks/Inbox/</source>
        <translation>/我的任务/收集箱/</translation>
    </message>
    <message>
        <location filename="../src/share/WizMisc.cpp" line="391"/>
        <source>/My Tasks/Completed/</source>
        <translation>/我的任务/已完成/</translation>
    </message>

Linux 自动更新的 AppImage 无法从 Memocast 启动

从 devtools 看到的错误信息如下:

ENOSYS: function not implemented, unlink '/run/user/1000/appimagelauncherfs/0007.AppImage'
3.js:1 ENOSYS: function not implemented, unlink '/run/user/1000/appimagelauncherfs/0007.AppImage'
app.js:1 ENOSYS: function not implemented, unlink '/run/user/1000/appimagelauncherfs/0007.AppImage'
3.js:1 ENOSYS: function not implemented, unlink '/run/user/1000/appimagelauncherfs/0007.AppImage'

导出笔记,无法导出图片

我笔记中的图片是以前在为知的客户端中创建的,切换到memocast中后,导出笔记时,只能导出文字,无法导出图片
ps: 我的笔记都是markdown笔记

几个小建议

  1. 自定义排序支持,当前的文件件排序是乱序的
  2. 自定义快捷键支持

引入更加稳定的图片上传方式

使用PicGo来上传图片,Neeto-Vue的本体将只保留为知官方图片服务的上传能力,摒弃其他冗余的上传方式。

使用PicGo也会带一些问题:

  • 必须要保证PicGo的服务是正常运作的
  • 必须要保证本机的对应端口可以被访问。

无法显示由为知内置编辑器建立的表格

无法显示由为知内置编辑器建立的表格
之前试过如果直接用 Typora 编辑笔记,也是一样无法显示的
不晓得能否做到兼容?
毕竟可视化方式拉个表格还是比写代码快也直观

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.