Skip to content

Commit

Permalink
feat(page-icon): add sidebar links inherited icons on load/add
Browse files Browse the repository at this point in the history
  • Loading branch information
yoyurec committed Oct 5, 2022
1 parent d64d025 commit ff11136
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 22 deletions.
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
</p>

* **Favicons** for external links! <a href="#-auto-favicons-for-external-links">🡖</a>
* **Pages icons** for internal links <a href="#-page-icons">🡖</a>
* **Pages icons** for internal links<a href="#-page-icons">🡖</a>
* Common page `icon::`
* Aliased page icon
* Inherited from props page (+ place icon on page title & current tab)
* Page icons`icon::`extended from Emoji to hundreds icons set via Nerd fonts support <a href="#-custom-page-icons">🡖</a>
* Custom **Journal icons** <a href="#-journal-icon">🡖</a>

## If you ❤ what i'm doing - you can support my work! ☕
<a href="https://www.buymeacoffee.com/yoyurec" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: 50px !important;width: 178px !important;" ></a>

## Install
From Logseq store - `Plugins -> Marketplace`.
From Logseq store - `Plugins -> Marketplace`

![](https://github.com/yoyurec/logseq-awesome-links/raw/main/screenshots/market.png)

Expand All @@ -33,25 +36,28 @@ From Logseq store - `Plugins -> Marketplace`.
### ✨ Page icons

Enable feature to show Logseq page (or aliased page) icon for internal links in content.
In addition you can config icon inheriting from related page proprty, to avoid manual setting `icon::` for common pages.
In addition you can config icon inheriting from page property referenced page, to avoid manual setting `icon::` for common pages.
For ex.:
* create "Projects" page, set `icon::` for it
* create "Some project" page, set `page-type:: [[Projects]]`
* set in plugin settings "Inherit icon from..." `page-type`
* ...and all pages with `page-type:: [[Projects]]` will have inherited "Projects" page icon!

Inherited icons also will be shown on current page title, current tab (if "Tabs" plugin installed) and sidebar.

![](https://github.com/yoyurec/logseq-awesome-links/raw/main/screenshots/page-icons.png)

### ✨ Custom page icons

3600+ icons combined from popular sets (Font Awesome, Material Design, Seti-UI, etc...)!
3600+ icons combined from popular sets (Font Awesome, Material Design, SetiUI, etc...)!
Native Logseq props `icon::` extended with Nerd icons font:
* Search in collection ([Icons Cheat Sheet](https://www.nerdfonts.com/cheat-sheet)),
* select
* press "Copy icon",
* paste to `icon::` props

Banners & Tabs plugin support included 😎
Feature can be disabled.

![](https://github.com/yoyurec/logseq-awesome-links/raw/main/screenshots/nerd-icons.png)

Expand All @@ -60,6 +66,7 @@ Banners & Tabs plugin support included 😎
### ✨ Journal icon

Can be customized in settings.
Delete value to disable feature.

![](https://github.com/yoyurec/logseq-awesome-links/raw/main/screenshots/journal-icon.png)

Expand Down
Binary file modified screenshots/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/css/awesomeLinks.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
line-height: 1.2em;
width: 1.4em;
}
/* sidebar */
.awLinks-sidebar-icon + .page-icon {
display: none !important;
}
/* content */
.is-awesomeLinks-int .page-icon.awLinks-page-icon {
display: inline-block;
Expand Down
3 changes: 3 additions & 0 deletions src/js/awesomeLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { pageIconsLoad, pageIconsUnload, toggleIconsFeature } from './modules/in
import { nerdFontLoad, nerdFontUnload, toggleNerdFonFeature } from './modules/internal';
import { faviconsLoad, faviconsUnload, toggleFaviconsFeature } from './modules/internal';
import { journalIconsLoad, journalIconsUnload, toggleJournalIconFeature } from './modules/internal';
import { sidebarIconsLoad, sidebarIconsUnload } from './modules/internal';
import { stopLinksObserver, runLinksObserver, initLinksObserver } from './modules/internal';

import '../css/awesomeLinks.css';
Expand All @@ -32,6 +33,7 @@ const runStuff = async () => {
nerdFontLoad();
faviconsLoad();
journalIconsLoad();
sidebarIconsLoad();
if (globalContext.pluginConfig?.featureFaviconsEnabled || globalContext.pluginConfig?.featurePageIconsEnabled) {
runLinksObserver();
}
Expand All @@ -43,6 +45,7 @@ const stopStuff = () => {
nerdFontUnload();
faviconsUnload();
journalIconsUnload();
sidebarIconsUnload();
stopLinksObserver();
body.classList.remove('is-awesomeLinks');
}
Expand Down
8 changes: 5 additions & 3 deletions src/js/modules/favIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import { doc, body } from './DOMContainers';
import { stopLinksObserver } from './internal';

// External links favicons
export const setFavicons = async (extLinkList: NodeListOf<HTMLAnchorElement>) => {
export const setFavicons = async (extLinkList?: NodeListOf<HTMLAnchorElement> | HTMLAnchorElement[]) => {
if (!extLinkList) {
extLinkList = doc.querySelectorAll('.external-link');
}
for (let i = 0; i < extLinkList.length; i++) {
const oldFav = extLinkList[i].querySelector('.page-icon.awLinks-link-icon');
if (oldFav) {
Expand Down Expand Up @@ -36,8 +39,7 @@ const removeFavicons = () => {
export const faviconsLoad = async () => {
if (globalContext.pluginConfig?.featureFaviconsEnabled) {
setTimeout(() => {
const extLinkList: NodeListOf<HTMLAnchorElement> = doc.querySelectorAll('.external-link');
setFavicons(extLinkList);
setFavicons();
}, 500);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/js/modules/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './nerdFont';
export * from './journalIcons';
export * from './favIcons';
export * from './titleIcon';
export * from './sidebarIcon';
22 changes: 15 additions & 7 deletions src/js/modules/linksObserver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { appContainer } from './DOMContainers';
import { setFavicons, setPageIcons, setTitleIcon } from './internal';
import { setFavicons, setPageIcons, setSidebarIcons, setTitleIcon } from './internal';

let linksObserver: MutationObserver, linksObserverConfig: MutationObserverInit;

Expand All @@ -20,15 +20,23 @@ const linksObserverCallback: MutationCallback = function (mutationsList) {
if (titleEl) {
setTitleIcon(titleEl);
}
// sidebar icon
console.log(addedNode);
if (addedNode.classList.contains('favorite-item') || addedNode.classList.contains('recent-item')) {
const sidebarLink = addedNode.querySelector('a') as HTMLAnchorElement;
if (sidebarLink) {
setSidebarIcons([sidebarLink]);
}
}
// favicons
const extLinkList = addedNode.querySelectorAll('.external-link') as NodeListOf<HTMLAnchorElement>;
if (extLinkList.length) {
setFavicons(extLinkList);
const extLink = addedNode.querySelector('.external-link') as HTMLAnchorElement;
if (extLink) {
setFavicons([extLink]);
}
// page icons
const linkList = addedNode.querySelectorAll('.ls-block .page-ref:not(.page-property-key)') as NodeListOf<HTMLAnchorElement>;
if (linkList.length) {
setPageIcons(linkList);
const pageLink = addedNode.querySelector('.ls-block .page-ref:not(.page-property-key)') as HTMLAnchorElement;
if (pageLink) {
setPageIcons([pageLink]);
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/js/modules/pageIcons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { searchIcon } from './queries';
import { setTitleIcon, removeTitleIcon } from './internal';
import { stopLinksObserver } from './internal';

export const setPageIcons = async (linkList: NodeListOf<HTMLAnchorElement>) => {
export const setPageIcons = async (linkList?: NodeListOf<HTMLAnchorElement> | HTMLAnchorElement[]) => {
if (!linkList) {
linkList = doc.querySelectorAll('.ls-block .page-ref:not(.page-property-key)');
}
for (let i = 0; i < linkList.length; i++) {
const linkItem = linkList[i];
const oldPageIcon = linkItem.querySelector('.page-icon.awLinks-page-icon');
Expand Down Expand Up @@ -34,8 +37,7 @@ const removePageIcons = () => {
}

export const pageIconsLoad = async () => {
const linkList: NodeListOf<HTMLAnchorElement> = doc.querySelectorAll('.ls-block .page-ref:not(.page-property-key)');
setPageIcons(linkList);
setPageIcons();
setTitleIcon();
}

Expand Down
40 changes: 40 additions & 0 deletions src/js/modules/sidebarIcon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { doc } from './DOMContainers';
import { searchIcon } from './queries';

export const setSidebarIcons = async (sidebarLinksList?: NodeListOf<HTMLAnchorElement> | HTMLAnchorElement[]) => {
if (!sidebarLinksList) {
sidebarLinksList = doc.querySelectorAll('.nav-contents-container :is(.favorite-item , .recent-item) .items-center');
}
for (let i = 0; i < sidebarLinksList.length; i++) {
const sidebarLinkItem = sidebarLinksList[i];
const defaultIcon = sidebarLinkItem.querySelector('.ui__icon');
if (!defaultIcon) {
continue;
}
const pageTitle = sidebarLinkItem.querySelector('.page-title')?.textContent;
if (!pageTitle) {
continue;
}
const pageIcon = await searchIcon(pageTitle);
if (pageIcon) {
sidebarLinkItem.insertAdjacentHTML('afterbegin', `<span class="page-icon awLinks-sidebar-icon">${pageIcon}</span>`);
}
}
}

const removeSidebarIcons = () => {
const pageIcons = doc.querySelectorAll('.nav-contents-container .page-icon.awLinks-sidebar-icon');
if (pageIcons.length) {
for (let i = 0; i < pageIcons.length; i++) {
pageIcons[i].remove();
}
}
}

export const sidebarIconsLoad = async () => {
setSidebarIcons();
}

export const sidebarIconsUnload = () => {
removeSidebarIcons();
}
12 changes: 7 additions & 5 deletions src/js/modules/titleIcon.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { doc } from './DOMContainers';
import { getInheritedPropsIcon } from './queries';

export const setTitleIcon = async (pageNameEl?: Element) => {
const title = pageNameEl || doc.querySelector('.ls-page-title');
if (title && !title.querySelector('.page-icon')) {
const pageName = title.textContent;
export const setTitleIcon = async (pageTitleEl?: Element | null) => {
if (!pageTitleEl) {
pageTitleEl = doc.querySelector('.ls-page-title');
}
if (pageTitleEl && !pageTitleEl.querySelector('.page-icon')) {
const pageName = pageTitleEl.textContent;
if (pageName) {
const titleIcon = await getInheritedPropsIcon(pageName);
if (titleIcon) {
title.insertAdjacentHTML('afterbegin', `<span class="page-icon awLinks-title-icon">${titleIcon}</span>`);
pageTitleEl.insertAdjacentHTML('afterbegin', `<span class="page-icon awLinks-title-icon">${titleIcon}</span>`);
setTabIcon(titleIcon);
}
}
Expand Down

0 comments on commit ff11136

Please sign in to comment.