mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Notes improvements
This commit is contained in:
parent
7de6a51d73
commit
28bbaaf53e
9 changed files with 115 additions and 83 deletions
|
@ -37,6 +37,12 @@ dependencies {
|
|||
api 'com.vladsch.flexmark:flexmark-util-format:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-util-html:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-util-visitor:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-tables:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-footnotes:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-definition:0.64.8'
|
||||
api 'com.vladsch.flexmark:flexmark-ext-anchorlink:0.64.8'
|
||||
|
||||
api files("$rootDir/gradle/gradle_scripts/markdowngenerator-1.3.1.1.jar")
|
||||
api files("$rootDir/gradle/gradle_scripts/vernacular-1.16.jar")
|
||||
|
|
|
@ -17,6 +17,7 @@ import io.xpipe.app.storage.DataStorage;
|
|||
import io.xpipe.app.storage.DataStoreColor;
|
||||
import io.xpipe.app.update.XPipeDistributionType;
|
||||
import io.xpipe.app.util.*;
|
||||
import io.xpipe.core.util.XPipeInstallation;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.beans.value.ObservableDoubleValue;
|
||||
|
@ -449,7 +450,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
|||
private static String getDefaultNotes() {
|
||||
if (DEFAULT_NOTES == null) {
|
||||
AppResources.with(AppResources.XPIPE_MODULE, "misc/notes_default.md", f -> {
|
||||
DEFAULT_NOTES = Files.readString(f);
|
||||
DEFAULT_NOTES = Files.readString(f).replace("__IMAGE__", XPipeInstallation.getLocalDefaultInstallationIcon().toString());
|
||||
});
|
||||
}
|
||||
return DEFAULT_NOTES;
|
||||
|
|
|
@ -12,11 +12,10 @@ import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
|||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.layout.Region;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
@ -37,20 +36,50 @@ public class StoreNotesComp extends Comp<StoreNotesComp.Structure> {
|
|||
.styleClass("notes-button")
|
||||
.grow(false, true)
|
||||
.hide(BindingsHelper.map(n, s -> s.getCommited() == null && s.getCurrent() == null))
|
||||
.padding(new Insets(5))
|
||||
.createStructure().get();
|
||||
button.prefWidthProperty().bind(button.heightProperty());
|
||||
|
||||
var prop = new SimpleStringProperty(n.getValue().getCurrent());
|
||||
var md = new MarkdownEditorComp(prop,"notes-" + wrapper.getName().getValue()).createStructure();
|
||||
|
||||
var popover = new AtomicReference<Popover>();
|
||||
button.setOnAction(e -> {
|
||||
if (n.getValue().getCurrent() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (popover.get() != null && popover.get().isShowing()) {
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
popover.set(createPopover(popover, prop));
|
||||
popover.get().show(button);
|
||||
e.consume();
|
||||
});
|
||||
prop.addListener((observable, oldValue, newValue) -> {
|
||||
n.setValue(new StoreNotes(n.getValue().getCommited(), newValue));
|
||||
});
|
||||
n.addListener((observable, oldValue, s) -> {
|
||||
prop.set(s.getCurrent());
|
||||
if (s.getCurrent() != null && oldValue.getCommited() == null && oldValue.isCommited()) {
|
||||
Platform.runLater(() -> {
|
||||
popover.set(createPopover(popover, prop));
|
||||
popover.get().show(button);
|
||||
});
|
||||
}
|
||||
});
|
||||
return new Structure(popover.get(), button);
|
||||
}
|
||||
|
||||
private Popover createPopover(AtomicReference<Popover> ref, Property<String> prop) {
|
||||
var n = wrapper.getNotes();
|
||||
var md = new MarkdownEditorComp(prop, "notes-" + wrapper.getName().getValue()).createStructure();
|
||||
var dialog = new DialogComp() {
|
||||
|
||||
@Override
|
||||
protected void finish() {
|
||||
n.setValue(new StoreNotes(n.getValue().getCurrent(), n.getValue().getCurrent()));
|
||||
popover.get().hide();
|
||||
ref.get().hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,7 +97,7 @@ public class StoreNotesComp extends Comp<StoreNotesComp.Structure> {
|
|||
@Override
|
||||
protected List<Comp<?>> customButtons() {
|
||||
return List.of(new ButtonComp(AppI18n.observable("cancel"), () -> {
|
||||
popover.get().hide();
|
||||
ref.get().hide();
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -78,23 +107,25 @@ public class StoreNotesComp extends Comp<StoreNotesComp.Structure> {
|
|||
}
|
||||
}.createRegion();
|
||||
|
||||
popover.set(createPopover(dialog));
|
||||
button.setOnAction(e -> {
|
||||
if (n.getValue().getCurrent() == null) {
|
||||
return;
|
||||
var popover = new Popover(dialog);
|
||||
popover.setCloseButtonEnabled(true);
|
||||
popover.setHeaderAlwaysVisible(true);
|
||||
popover.setDetachable(true);
|
||||
popover.setTitle(wrapper.getName().getValue());
|
||||
popover.setMaxWidth(400);
|
||||
popover.setHeight(600);
|
||||
popover.showingProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
n.setValue(new StoreNotes(n.getValue().getCommited(), n.getValue().getCommited()));
|
||||
DataStorage.get().saveAsync();
|
||||
ref.set(null);
|
||||
}
|
||||
|
||||
if (popover.get().isShowing()) {
|
||||
e.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
popover.get().show(button);
|
||||
e.consume();
|
||||
});
|
||||
AppFont.small(popover.getContentNode());
|
||||
|
||||
md.getEditButton().addEventFilter(ActionEvent.ANY, event -> {
|
||||
if (!popover.get().isDetached()) {
|
||||
popover.get().setDetached(true);
|
||||
if (!popover.isDetached()) {
|
||||
popover.setDetached(true);
|
||||
event.consume();
|
||||
Platform.runLater(() -> {
|
||||
Platform.runLater(() -> {
|
||||
|
@ -103,35 +134,7 @@ public class StoreNotesComp extends Comp<StoreNotesComp.Structure> {
|
|||
});
|
||||
}
|
||||
});
|
||||
popover.get().showingProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (!newValue) {
|
||||
n.setValue(new StoreNotes(n.getValue().getCommited(), n.getValue().getCommited()));
|
||||
DataStorage.get().saveAsync();
|
||||
}
|
||||
});
|
||||
prop.addListener((observable, oldValue, newValue) -> {
|
||||
n.setValue(new StoreNotes(n.getValue().getCommited(), newValue));
|
||||
});
|
||||
n.addListener((observable, oldValue, s) -> {
|
||||
prop.set(s.getCurrent());
|
||||
if (s.getCurrent() != null && oldValue.getCommited() == null && oldValue.isCommited()) {
|
||||
Platform.runLater(() -> {
|
||||
popover.get().show(button);
|
||||
});
|
||||
}
|
||||
});
|
||||
return new Structure(popover.get(), button);
|
||||
}
|
||||
|
||||
private Popover createPopover(Region content) {
|
||||
var popover = new Popover(content);
|
||||
popover.setCloseButtonEnabled(true);
|
||||
popover.setHeaderAlwaysVisible(true);
|
||||
popover.setDetachable(true);
|
||||
popover.setTitle(wrapper.getName().getValue());
|
||||
popover.setMaxWidth(400);
|
||||
popover.setHeight(600);
|
||||
AppFont.small(popover.getContentNode());
|
||||
return popover;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,39 @@
|
|||
package io.xpipe.app.util;
|
||||
|
||||
import com.vladsch.flexmark.ext.anchorlink.AnchorLinkExtension;
|
||||
import com.vladsch.flexmark.ext.definition.DefinitionExtension;
|
||||
import com.vladsch.flexmark.ext.footnotes.FootnoteExtension;
|
||||
import com.vladsch.flexmark.ext.gfm.strikethrough.StrikethroughExtension;
|
||||
import com.vladsch.flexmark.ext.gfm.tasklist.TaskListExtension;
|
||||
import com.vladsch.flexmark.ext.tables.TablesExtension;
|
||||
import com.vladsch.flexmark.html.HtmlRenderer;
|
||||
import com.vladsch.flexmark.parser.Parser;
|
||||
import com.vladsch.flexmark.util.ast.Document;
|
||||
import com.vladsch.flexmark.util.data.MutableDataSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class MarkdownHelper {
|
||||
|
||||
public static String toHtml(String value, UnaryOperator<String> htmlTransformation) {
|
||||
MutableDataSet options = new MutableDataSet();
|
||||
MutableDataSet options = new MutableDataSet().set(Parser.EXTENSIONS, Arrays.asList(
|
||||
StrikethroughExtension.create(),
|
||||
TaskListExtension.create(),
|
||||
TablesExtension.create(),
|
||||
FootnoteExtension.create(),
|
||||
DefinitionExtension.create(),
|
||||
AnchorLinkExtension.create()
|
||||
))
|
||||
.set(FootnoteExtension.FOOTNOTE_BACK_LINK_REF_CLASS,"footnotes")
|
||||
.set(TablesExtension.WITH_CAPTION, false)
|
||||
.set(TablesExtension.COLUMN_SPANS, false)
|
||||
.set(TablesExtension.MIN_HEADER_ROWS, 1)
|
||||
.set(TablesExtension.MAX_HEADER_ROWS, 1)
|
||||
.set(TablesExtension.APPEND_MISSING_COLUMNS, true)
|
||||
.set(TablesExtension.DISCARD_EXTRA_COLUMNS, true)
|
||||
.set(TablesExtension.HEADER_SEPARATOR_COLUMN_MATCH, true)
|
||||
.set(HtmlRenderer.GENERATE_HEADER_ID,true);
|
||||
Parser parser = Parser.builder(options).build();
|
||||
HtmlRenderer renderer = HtmlRenderer.builder(options).build();
|
||||
Document document = parser.parse(value);
|
||||
|
|
|
@ -99,29 +99,14 @@ doc](#an-h2-header). Here's a footnote [^1].
|
|||
|
||||
Tables can look like this:
|
||||
|
||||
size material color
|
||||
---- ------------ ------------
|
||||
9 leather brown
|
||||
10 hemp canvas natural
|
||||
11 glass transparent
|
||||
| size | material | color |
|
||||
|------|-------------|-------------|
|
||||
| 9 | leather | brown |
|
||||
| 10 | hemp canvas | natural |
|
||||
| 11 | glass | transparent |
|
||||
|
||||
Table: Shoes, their sizes, and what they're made of
|
||||
|
||||
(The above is the caption for the table.) Pandoc also supports
|
||||
multi-line tables:
|
||||
|
||||
-------- -----------------------
|
||||
keyword text
|
||||
-------- -----------------------
|
||||
red Sunsets, apples, and
|
||||
other red or reddish
|
||||
things.
|
||||
|
||||
green Leaves, grass, frogs
|
||||
and other things it's
|
||||
not easy being.
|
||||
-------- -----------------------
|
||||
|
||||
A horizontal rule follows.
|
||||
|
||||
***
|
||||
|
@ -146,7 +131,7 @@ Here's a "line block":
|
|||
|
||||
and images can be specified like so:
|
||||
|
||||
![example image](example-image.jpg "An exemplary image")
|
||||
![example image](__IMAGE__ "An exemplary image")
|
||||
|
||||
Inline math equations go in like so: $\omega = d\phi / dt$. Display
|
||||
math should get its own line and be put in in double-dollarsigns:
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
-fx-opacity: 1.0;
|
||||
}
|
||||
|
||||
.expand-button:hover, .root:key-navigation .expand-button:focused, .quick-access-button:hover, .root:key-navigation .quick-access-button:focused {
|
||||
.notes-button:hover, .root:key-navigation .notes-button:focused, .expand-button:hover, .root:key-navigation .expand-button:focused, .quick-access-button:hover, .root:key-navigation .quick-access-button:focused {
|
||||
-fx-background-color: -color-neutral-muted;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ html {
|
|||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
margin: 0;
|
||||
padding: 0 1em 1em 1em;
|
||||
padding: 1em;
|
||||
color: #c9d1d9;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
font-size: 14px;
|
||||
|
@ -560,17 +560,21 @@ html {
|
|||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body table th {
|
||||
.markdown-body table {
|
||||
color: #c9d1d9;
|
||||
}
|
||||
|
||||
.markdown-body table thead th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body table th,
|
||||
.markdown-body table td {
|
||||
padding: 6px 13px;
|
||||
.markdown-body table thead th,
|
||||
.markdown-body table tbody td {
|
||||
padding: 6px 13px !important;
|
||||
border: 1px solid #30363d;
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
.markdown-body table thead tr .markdown-body table tbody tr {
|
||||
background-color: #0d1117;
|
||||
border-top: 1px solid #21262d;
|
||||
}
|
||||
|
|
|
@ -662,17 +662,21 @@ html {
|
|||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.markdown-body table th {
|
||||
.markdown-body table {
|
||||
color: #24292f;
|
||||
}
|
||||
|
||||
.markdown-body table thead th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown-body table th,
|
||||
.markdown-body table td {
|
||||
padding: 6px 13px;
|
||||
.markdown-body table thead th,
|
||||
.markdown-body table tbody td {
|
||||
padding: 6px 13px !important;
|
||||
border: 1px solid #d0d7de;
|
||||
}
|
||||
|
||||
.markdown-body table tr {
|
||||
.markdown-body table thead tr .markdown-body table tbody tr {
|
||||
background-color: #ffffff;
|
||||
border-top: 1px solid hsla(210, 18%, 87%, 1);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,12 @@ extraJavaModuleInfo {
|
|||
mergeJar('com.vladsch.flexmark:flexmark-util-collection')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-util-misc')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-util-visitor')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-tables')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-gfm-strikethrough')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-gfm-tasklist')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-footnotes')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-definition')
|
||||
mergeJar('com.vladsch.flexmark:flexmark-ext-anchorlink')
|
||||
exportAllPackages()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue