├── .gitignore
├── package.json
├── index.html
├── README.md
├── LICENSE.md
├── .github
└── workflows
│ └── publish.yml
├── wide-eyed.svg
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package-lock.json
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "logseq-wide-eyed",
3 | "version": "1.0.6",
4 | "author": "Mario T. Lanza",
5 | "main": "index.html",
6 | "description": "Toggles the appearance and/or visibility of select blocks",
7 | "license": "MIT",
8 | "browserslist": [
9 | "chrome 80"
10 | ],
11 | "logseq": {
12 | "id": "logseq-wide-eyed",
13 | "title": "Wide Eyed",
14 | "icon": "wide-eyed.svg"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Logseq Wide Eyed
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Logseq Wide Eyed Plugin
2 |
3 | Toggle the visibility of completed and canceled to-dos.
4 |
5 | Version 2 replaced the guts with the internals of [Style Carousel](https://github.com/mlanza/logseq-style-carousel). The prior implementation is no longer supported. The only difference is the icon font set used for the ever-present eye.
6 |
7 | Since Style Carousel and Wide Eyed are internally the same, do not install both. It's one or the other.
8 |
9 | This plugin may eventually be deprecated due to the existence of Style Carousel which has the same default behavior. Furthermore, it [can be customized](https://github.com/mlanza/logseq-style-carousel#using-the-eye-icon-from-wide-eyed) to use the familiar Wide Eyed eye icon. Please consider making the switch before that happens.
10 |
11 | ## License
12 | [MIT](./LICENSE.md)
13 |
14 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2022 Mario T. Lanza
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Build plugin
2 |
3 | on:
4 | push:
5 | # Sequence of patterns matched against refs/tags
6 | tags:
7 | - "*" # Push events to matching any tag format, i.e. 1.0, 20.15.10
8 |
9 | env:
10 | PLUGIN_NAME: logseq-wide-eyed
11 |
12 | jobs:
13 | build:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v2
18 | - name: Use Node.js
19 | uses: actions/setup-node@v1
20 | with:
21 | node-version: "14.x" # You might need to adjust this value to your own version
22 | - name: Build
23 | id: build
24 | run: |
25 | mkdir ${{ env.PLUGIN_NAME }}
26 | cp README.md package.json wide-eyed.svg index.js index.html ${{ env.PLUGIN_NAME }}
27 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }}
28 | ls
29 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)"
30 |
31 | - name: Create Release
32 | uses: ncipollo/release-action@v1
33 | id: create_release
34 | env:
35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 | VERSION: ${{ github.ref }}
37 | with:
38 | allowUpdates: true
39 | draft: false
40 | prerelease: false
41 |
42 | - name: Upload zip file
43 | id: upload_zip
44 | uses: actions/upload-release-asset@v1
45 | env:
46 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47 | with:
48 | upload_url: ${{ steps.create_release.outputs.upload_url }}
49 | asset_path: ./${{ env.PLUGIN_NAME }}.zip
50 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip
51 | asset_content_type: application/zip
52 |
53 | - name: Upload package.json
54 | id: upload_metadata
55 | uses: actions/upload-release-asset@v1
56 | env:
57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58 | with:
59 | upload_url: ${{ steps.create_release.outputs.upload_url }}
60 | asset_path: ./package.json
61 | asset_name: package.json
62 | asset_content_type: application/json
63 |
64 |
--------------------------------------------------------------------------------
/wide-eyed.svg:
--------------------------------------------------------------------------------
1 |
2 |
60 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | "buttons": {
3 | "todos": {
4 | "refreshRate": 5,
5 | "hits": ["text-decoration: underline;", ""],
6 | "styles": [{
7 | "tooltip": "Without closed tasks",
8 | "char": "\\e6ed",
9 | "hits": "div#main-content-container div[data-refs-self*='\"done\"'], div#main-content-container div[data-refs-self*='\"canceled\"']",
10 | "style": "div[data-refs-self*='\"done\"']:not(:focus-within), div[data-refs-self*='\"canceled\"']:not(:focus-within) {display: none;}"
11 | },{
12 | "tooltip": "With closed tasks",
13 | "char": "\\e600",
14 | "hits": "div#main-content-container div[data-refs-self*='\"done\"'], div#main-content-container div[data-refs-self*='\"canceled\"']",
15 | "style": "div#main-content-container:hover div[data-refs-self*='\"done\"'] span.inline, div#main-content-container:hover div[data-refs-self*='\"canceled\"'] span.inline {text-decoration: underline wavy;}"
16 | }]
17 | }
18 | }
19 | };
20 |
21 | const state = {};
22 |
23 | async function getPage(){
24 | let tries = 30;
25 | return new Promise(function(resolve, reject){
26 | const iv = setInterval(async function(){
27 | const page = await logseq.Editor.getCurrentPage();
28 | if (page || tries <= 0) {
29 | clearInterval(iv);
30 | resolve(page);
31 | }
32 | tries--;
33 | if (tries < 0) {
34 | clearInterval(iv);
35 | reject(page);
36 | }
37 | }, 500);
38 | });
39 | }
40 |
41 | function setButton(key, char, tooltip, status){
42 | top.document.body.setAttribute(`data-sc-${key}`, status || "");
43 | logseq.App.registerUIItem('toolbar', {
44 | key: `button-${key}`,
45 | template: `
46 |
47 |
48 |
49 | `,
50 | });
51 | logseq.provideStyle({
52 | key: `icon-${key}`,
53 | style: `
54 | .eye[data-key="${key}"] i:before {
55 | content: "${char}";
56 | }`
57 | });
58 | }
59 |
60 | async function cycle(el) {
61 | const key = el.dataset.key,
62 | st = state[key],
63 | btn = config.buttons[key];
64 | st.idx = btn.styles[st.idx + 1] ? st.idx + 1 : 0;
65 | await refresh(key, btn, st);
66 | }
67 |
68 | async function refresh(key, btn, state){
69 | const {char, tooltip, status, style, hits} = btn.styles[state.idx];
70 | state.hits = hits;
71 | style && logseq.provideStyle({
72 | key: `active-${key}`,
73 | style
74 | });
75 | setButton(key, char, tooltip, status);
76 | detectHits(key, btn, state);
77 | }
78 |
79 | function detectHits(key, config, state){
80 | if (state.hits) {
81 | const el = top.document.querySelector(state.hits);
82 | const style = el ? config.hits[0] : config.hits[1];
83 | logseq.provideStyle({
84 | key: `hits-${key}`,
85 | style: `
86 | .eye[data-key="${key}"] i:before {
87 | ${style};
88 | }`
89 | });
90 | }
91 | }
92 |
93 | function refreshHits(key, config, state){
94 | (config.refreshRate || 0) > 0 && setInterval(function(){
95 | detectHits(key, config, state);
96 | }, config.refreshRate * 1000);
97 | }
98 |
99 | function createModel(){
100 | return {refresh, cycle};
101 | }
102 |
103 | async function main(){
104 | Object.assign(config, logseq.settings);
105 |
106 | logseq.provideStyle({
107 | style: `
108 | @import url("https://at.alicdn.com/t/font_2409735_haugsknp36e.css");
109 | .eye {
110 | font-size: 20px;
111 | }
112 | .eye i:before {
113 | font-family: iconfont !important;
114 | font-style: normal;
115 | color: var(--ls-primary-text-color);
116 | }`
117 | });
118 |
119 | for (let key in config.buttons) {
120 | const btn = config.buttons[key];
121 | if (btn.disabled) {
122 | delete config.buttons[key];
123 | } else {
124 | const {char, tooltip, status} = btn.styles[0];
125 | state[key] = {idx: 0};
126 | setButton(key, char, tooltip, status);
127 | }
128 | }
129 |
130 | await getPage();
131 |
132 | for (let key in config.buttons) {
133 | const btn = config.buttons[key],
134 | st = state[key];
135 | await refresh(key, btn, st);
136 | refreshHits(key, btn, st);
137 | }
138 |
139 | logseq.App.onRouteChanged(async function(e){
140 | await getPage();
141 | for (let key in config.buttons) {
142 | refresh(key, config.buttons[key], state[key]);
143 | }
144 | });
145 | }
146 |
147 | logseq.ready(createModel(), main).catch(console.error.bind(console));
148 |
--------------------------------------------------------------------------------