Skip to content

Commit

Permalink
Support page aliases (#198)
Browse files Browse the repository at this point in the history
* fix: Fixed the default keyMap

* feat: Finished the note aliases popover

* feat: Supported to search for note aliases

* feat: Also analyzed link in tokens

* feat: Tried to fix the note aliases search

* feat: Upgraded EchoMD to 1.0.1

* fix: Delete aliases if empty
  • Loading branch information
shd101wyy authored Feb 28, 2021
1 parent e7e11fe commit bc781b0
Show file tree
Hide file tree
Showing 14 changed files with 347 additions and 67 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@0xgg/echomd": "^1.0.0",
"@0xgg/echomd": "^1.0.1",
"@dicebear/avatars": "^4.0.8",
"@dicebear/avatars-female-sprites": "^4.0.8",
"@dicebear/avatars-human-sprites": "^4.0.8",
Expand Down
112 changes: 112 additions & 0 deletions src/components/NoteAliasPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import {
Box,
IconButton,
List,
ListItem,
Popover,
TextField,
Typography,
} from "@material-ui/core";
import { createStyles, makeStyles, Theme } from "@material-ui/core/styles";
import clsx from "clsx";
import { TrashCan } from "mdi-material-ui";
import React, { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";

const useStyles = makeStyles((theme: Theme) =>
createStyles({
menuItemOverride: {
"cursor": "default",
"padding": `0 0 0 ${theme.spacing(2)}px`,
"&:hover": {
backgroundColor: "inherit",
},
},
menuItemTextField: {
paddingRight: theme.spacing(2),
},
}),
);
interface Props {
anchorElement: HTMLElement;
onClose: () => void;
addAlias: (alias: string) => void;
deleteAlias: (alias: string) => void;
aliases: string[];
}
export function NoteAliasPopover(props: Props) {
const classes = useStyles(props);
const { t } = useTranslation();
const [alias, setAlias] = useState<string>("");

const addAlias = useCallback(
(alias: string) => {
if (!alias || alias.trim().length === 0) {
return;
}
props.addAlias(alias);
setAlias("");
},
[props],
);

useEffect(() => {
setAlias("");
}, [props.anchorElement]);

return (
<Popover
open={Boolean(props.anchorElement)}
anchorEl={props.anchorElement}
keepMounted
onClose={props.onClose}
>
<List>
<ListItem
className={clsx(classes.menuItemOverride, classes.menuItemTextField)}
>
<TextField
placeholder={t("general/add-an-alias")}
fullWidth={true}
autoFocus={true}
onKeyUp={(event) => {
if (event.which === 13) {
addAlias(alias);
}
}}
onChange={(event) => setAlias(event.target.value)}
value={alias}
></TextField>
</ListItem>
{props.aliases.length > 0 ? (
props.aliases.map((alias) => {
return (
<ListItem key={alias} className={clsx(classes.menuItemOverride)}>
<Box
style={{
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
width: "100%",
}}
>
<Typography>{alias}</Typography>
<IconButton onClick={() => props.deleteAlias(alias)}>
<TrashCan></TrashCan>
</IconButton>
</Box>
</ListItem>
);
})
) : (
<ListItem className={clsx(classes.menuItemOverride)}>
<Typography style={{ margin: "8px 0" }}>
{t("general/no-aliases")}
</Typography>
</ListItem>
)}
</List>
</Popover>
);
}
53 changes: 36 additions & 17 deletions src/components/NotePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -601,12 +601,10 @@ export default function NotePanel(props: Props) {
const removeHighlightClass = () => {
element.classList.remove("reference-highlight");
};
previewElement.current.addEventListener(
"click",
removeHighlightClass,
);
const previewElementCurrent = previewElement.current;
previewElementCurrent.addEventListener("click", removeHighlightClass);
return () => {
previewElement.current.removeEventListener(
previewElementCurrent.removeEventListener(
"click",
removeHighlightClass,
);
Expand Down Expand Up @@ -1058,6 +1056,7 @@ export default function NotePanel(props: Props) {
);
return result["title"] + ".md" === filePath;
},
fields: ["title"],
});
const commands: {
text: string;
Expand Down Expand Up @@ -1105,24 +1104,43 @@ export default function NotePanel(props: Props) {
.replace(/^\[+/, "");
const searchResults = props.notebook.search.search(currentWord, {
fuzzy: true,
fields: ["title", "aliases", "filePath"],
});
const commands: {
text: string;
displayText: string;
}[] = searchResults.map((searchResult: any) => {
}[] = [];
for (let i = 0; i < searchResults.length; i++) {
const searchResult = searchResults[i];
const filtPath = path.relative(
path.dirname(path.join(note.notebookPath, note.filePath)),
path.join(note.notebookPath, searchResult.filePath),
);
const val =
searchResult.title + ".md" === filtPath
? `[[${searchResult.title}]]`
: `[[${filtPath}|${searchResult.title}]]`;
return {
text: val,
displayText: val,
};
});
const aliases = searchResult.aliases
.split("|")
.concat(searchResult.title) as string[];
const terms = searchResult.terms;
aliases.forEach((alias) => {
let find = true;
for (let i = 0; i < terms.length; i++) {
const lower = alias.toLocaleLowerCase();
if (lower.indexOf(terms[i]) < 0) {
find = false;
break;
}
}
if (find) {
const val =
alias + ".md" === filtPath
? `[[${alias}]]`
: `[[${filtPath}|${alias}]]`;
commands.push({
text: val,
displayText: val,
});
}
});
}
return {
list: commands,
from: { line, ch: start - 1 },
Expand Down Expand Up @@ -1202,12 +1220,13 @@ export default function NotePanel(props: Props) {
};

editor.on("changes", update);
tocElement.current.addEventListener("click", tocClick, true);
const tocElementCurrent = tocElement.current;
tocElementCurrent.addEventListener("click", tocClick, true);
update();

return () => {
editor.off("changes", update);
tocElement.current.removeEventListener("click", tocClick);
tocElementCurrent.removeEventListener("click", tocClick);
};
}, [editor, editorMode, previewElement, tocElement, note, tocEnabled]);

Expand Down
40 changes: 40 additions & 0 deletions src/components/NotePopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ShareVariant,
Star,
StarOutline,
TooltipEdit,
} from "mdi-material-ui";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
Expand All @@ -42,6 +43,7 @@ import { printPreview } from "../utilities/preview";
import { copyToClipboard } from "../utilities/utils";
import ChangeFilePathDialog from "./ChangeFilePathDialog";
import { DeleteNoteDialog } from "./DeleteNoteDialog";
import { NoteAliasPopover } from "./NoteAliasPopover";

const useStyles = makeStyles((theme: Theme) =>
createStyles({
Expand Down Expand Up @@ -75,6 +77,8 @@ export default function NotePopover(props: Props) {
] = useState<boolean>(false);
const [needsToPrint, setNeedsToPrint] = useState<boolean>(false);
const [shareAnchorEl, setShareAnchorEl] = useState<HTMLElement>(null);
const [noteAliasAnchorEl, setNoteAliasAnchorEl] = useState<HTMLElement>(null);
const [aliases, setAliases] = useState<string[]>(note.config.aliases);
const theme = useTheme();
const { t } = useTranslation();
const crossnoteContainer = CrossnoteContainer.useContainer();
Expand Down Expand Up @@ -225,6 +229,15 @@ export default function NotePopover(props: Props) {
primary={t("general/change-file-path")}
></ListItemText>
</ListItem>
<ListItem
button
onClick={(event) => setNoteAliasAnchorEl(event.currentTarget)}
>
<ListItemIcon>
<TooltipEdit></TooltipEdit>
</ListItemIcon>
<ListItemText primary={t("general/edit-note-alias")}></ListItemText>
</ListItem>
<ListItem
button
onClick={() => {
Expand Down Expand Up @@ -295,6 +308,33 @@ export default function NotePopover(props: Props) {
tabNode={props.tabNode}
note={note}
></ChangeFilePathDialog>
<NoteAliasPopover
anchorElement={noteAliasAnchorEl}
onClose={() => {
setNoteAliasAnchorEl(null);
}}
addAlias={(alias) => {
crossnoteContainer
.addNoteAlias(
props.tabNode,
note.notebookPath,
note.filePath,
alias,
)
.then((aliases) => setAliases(aliases));
}}
deleteAlias={(alias) => {
crossnoteContainer
.deleteNoteAlias(
props.tabNode,
note.notebookPath,
note.filePath,
alias,
)
.then((aliases) => setAliases(aliases));
}}
aliases={aliases}
></NoteAliasPopover>
<Popover
open={Boolean(shareAnchorEl)}
anchorEl={shareAnchorEl}
Expand Down
53 changes: 53 additions & 0 deletions src/containers/crossnote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,57 @@ function useCrossnoteContainer(initialState: InitialState) {
[getNotebookAtPath, updateNoteConfig],
);

const addNoteAlias = useCallback(
async (
tabNode: TabNode,
notebookPath: string,
noteFilePath: string,
alias: string,
) => {
const notebook = getNotebookAtPath(notebookPath);
if (!notebook) {
return;
}
const note = await notebook.getNote(noteFilePath);
const aliases: string[] = note.config.aliases || [];
const newAliases = aliases.concat(alias);
const newConfig = Object.assign({}, note.config, {
aliases: newAliases,
});
await updateNoteConfig(tabNode, notebookPath, noteFilePath, newConfig);
notebook.search.addAlias(noteFilePath, alias);
return newAliases;
},
[getNotebookAtPath, updateNoteConfig],
);

const deleteNoteAlias = useCallback(
async (
tabNode: TabNode,
notebookPath: string,
noteFilePath: string,
alias: string,
) => {
const notebook = getNotebookAtPath(notebookPath);
if (!notebook) {
return;
}
const note = await notebook.getNote(noteFilePath);
const aliases: string[] = note.config.aliases || [];
const newAliases = aliases.filter((a) => a !== alias);
const newConfig = Object.assign({}, note.config, {
aliases: newAliases,
});
if (!newAliases.length) {
delete newConfig.aliases;
}
await updateNoteConfig(tabNode, notebookPath, noteFilePath, newConfig);
notebook.search.deleteAlias(noteFilePath, alias);
return newAliases;
},
[getNotebookAtPath, updateNoteConfig],
);

const getStatus = useCallback(
async (notebookPath: string, filePath: string) => {
const notebook = getNotebookAtPath(notebookPath);
Expand Down Expand Up @@ -760,6 +811,8 @@ Please also check the [Explore](https://crossnote.app/explore) section to discov
openLocalNotebook,
togglePin,
toggleFavorite,
addNoteAlias,
deleteNoteAlias,
isAddingNotebook,
isPushingNotebook,
isPullingNotebook,
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/lang/enUS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export const enUS = {
"general/echomd": "Edit",
"general/tags": "Tags",
"general/add-a-tag": "Add a tag",
"general/edit-note-alias": "Edit note alias",
"general/no-aliases": "No aliases",
"general/add-an-alias": "Add an alias",
"general/private": "Private",
"general/public": "Public",
"general/friends-only": "Friends only",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/lang/jaJP.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export const jaJP = {
"general/echomd": "編集",
"general/tags": "タグ",
"general/add-a-tag": "タグを追加する",
"general/edit-note-alias": "ノート エイリアスの編集",
"general/no-aliases": "エイリアスなし",
"general/add-an-alias": "エイリアスを追加する",
"general/private": "民間",
"general/public": "公開可見",
"general/friends-only": "友達にのみ表示",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/lang/zhCN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export const zhCN = {
"general/echomd": "编辑",
"general/tags": "标签",
"general/add-a-tag": "添加一个标签",
"general/edit-note-alias": "编辑笔记别名",
"general/no-aliases": "没有别名",
"general/add-an-alias": "添加一个别名",
"general/private": "私有",
"general/public": "公开可见",
"general/friends-only": "仅好友可见",
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/lang/zhTW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export const zhTW = {
"general/echomd": "編輯",
"general/tags": "標籤",
"general/add-a-tag": "添加一個標籤",
"general/edit-note-alias": "編輯筆記別名",
"general/no-aliases": "沒有別名",
"general/add-an-alias": "添加壹個別名",
"general/private": "私有",
"general/public": "公開可見",
"general/friends-only": "僅好友可見",
Expand Down
Loading

0 comments on commit bc781b0

Please sign in to comment.