Add connection notes

This commit is contained in:
crschnick 2024-05-20 01:36:56 +00:00
parent ef22578d71
commit 7de6a51d73
24 changed files with 542 additions and 28 deletions

View file

@ -0,0 +1,80 @@
package io.xpipe.app.comp.base;
import atlantafx.base.theme.Styles;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.util.FileOpener;
import javafx.application.Platform;
import javafx.beans.property.Property;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import lombok.Builder;
import lombok.Value;
public class MarkdownEditorComp extends Comp<MarkdownEditorComp.Structure> {
private final Property<String> value;
private final String identifier;
public MarkdownEditorComp(
Property<String> value, String identifier) {
this.value = value;
this.identifier = identifier;
}
private Button createOpenButton() {
return new IconButtonComp(
"mdal-edit",
() -> FileOpener.openString(
identifier + ".md",
this,
value.getValue(),
(s) -> {
Platform.runLater(() -> value.setValue(s));
}))
.styleClass("edit-button")
.apply(struc -> struc.get().getStyleClass().remove(Styles.FLAT))
.createStructure()
.get();
}
@Override
public Structure createBase() {
var markdown = new MarkdownComp(value, s -> s).createRegion();
var editButton = createOpenButton();
var pane = new AnchorPane(markdown, editButton);
pane.setPickOnBounds(false);
AnchorPane.setTopAnchor(editButton, 10.0);
AnchorPane.setRightAnchor(editButton, 10.0);
return new Structure(pane, markdown, editButton);
}
@Value
@Builder
public static class TextAreaStructure implements CompStructure<StackPane> {
StackPane pane;
TextArea textArea;
@Override
public StackPane get() {
return pane;
}
}
@Value
@Builder
public static class Structure implements CompStructure<AnchorPane> {
AnchorPane pane;
Region markdown;
Button editButton;
@Override
public AnchorPane get() {
return pane;
}
}
}

View file

@ -72,6 +72,7 @@ public class DenseStoreEntryComp extends StoreEntryComp {
return grid.getWidth() / 2.5;
},
grid.widthProperty()));
var notes = new StoreNotesComp(wrapper).createRegion();
if (showIcon) {
var storeIcon = createIcon(30, 24);
@ -92,7 +93,8 @@ public class DenseStoreEntryComp extends StoreEntryComp {
nameCC.setMinWidth(100);
nameCC.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().addAll(nameCC);
var nameBox = new HBox(name);
var nameBox = new HBox(name, notes);
nameBox.setSpacing(8);
nameBox.setAlignment(Pos.CENTER_LEFT);
grid.addRow(0, nameBox);

View file

@ -20,6 +20,7 @@ public class StandardStoreEntryComp extends StoreEntryComp {
protected Region createContent() {
var name = createName().createRegion();
var notes = new StoreNotesComp(wrapper).createRegion();
var grid = new GridPane();
grid.setHgap(7);
@ -29,7 +30,10 @@ public class StandardStoreEntryComp extends StoreEntryComp {
grid.add(storeIcon, 0, 0, 1, 2);
grid.getColumnConstraints().add(new ColumnConstraints(66));
grid.add(name, 1, 0);
var nameAndNotes = new HBox(name, notes);
nameAndNotes.setSpacing(8);
nameAndNotes.setAlignment(Pos.CENTER_LEFT);
grid.add(nameAndNotes, 1, 0);
grid.add(createSummary(), 1, 1);
var nameCC = new ColumnConstraints();
nameCC.setMinWidth(100);

View file

@ -1,10 +1,8 @@
package io.xpipe.app.comp.store;
import atlantafx.base.theme.Styles;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.core.App;
import io.xpipe.app.core.AppActionLinkDetector;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.*;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
@ -12,13 +10,13 @@ import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.app.fxcomps.impl.*;
import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreColor;
import io.xpipe.app.update.XPipeDistributionType;
import io.xpipe.app.util.*;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableDoubleValue;
@ -29,13 +27,11 @@ import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import atlantafx.base.theme.Styles;
import org.kordamp.ikonli.javafx.FontIcon;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
@ -422,6 +418,14 @@ public abstract class StoreEntryComp extends SimpleComp {
contextMenu.getItems().add(color);
}
var notes = new MenuItem(AppI18n.get("addNotes"), new FontIcon("mdi2n-note-text"));
notes.setOnAction(event -> {
wrapper.getNotes().setValue(new StoreNotes(null, getDefaultNotes()));
event.consume();
});
notes.visibleProperty().bind(BindingsHelper.map(wrapper.getNotes(), s -> s.getCommited() == null));
contextMenu.getItems().add(notes);
var del = new MenuItem(AppI18n.get("remove"), new FontIcon("mdal-delete_outline"));
del.disableProperty()
.bind(Bindings.createBooleanBinding(
@ -439,9 +443,15 @@ public abstract class StoreEntryComp extends SimpleComp {
return contextMenu;
}
protected ColumnConstraints createShareConstraint(Region r, double share) {
var cc = new ColumnConstraints();
cc.prefWidthProperty().bind(Bindings.createDoubleBinding(() -> r.getWidth() * share, r.widthProperty()));
return cc;
private static String DEFAULT_NOTES = null;
private static String getDefaultNotes() {
if (DEFAULT_NOTES == null) {
AppResources.with(AppResources.XPIPE_MODULE, "misc/notes_default.md", f -> {
DEFAULT_NOTES = Files.readString(f);
});
}
return DEFAULT_NOTES;
}
}

View file

@ -39,6 +39,7 @@ public class StoreEntryWrapper {
private final Property<DataStoreColor> color = new SimpleObjectProperty<>();
private final Property<StoreCategoryWrapper> category = new SimpleObjectProperty<>();
private final Property<String> summary = new SimpleObjectProperty<>();
private final Property<StoreNotes> notes;
public StoreEntryWrapper(DataStoreEntry entry) {
this.entry = entry;
@ -60,6 +61,7 @@ public class StoreEntryWrapper {
actionProviders.put(dataStoreActionProvider, new SimpleBooleanProperty(true));
});
this.defaultActionProvider = new SimpleObjectProperty<>();
this.notes = new SimpleObjectProperty<>(new StoreNotes(entry.getNotes(), entry.getNotes()));
setupListeners();
}
@ -96,6 +98,12 @@ public class StoreEntryWrapper {
entry.addListener(() -> PlatformThread.runLaterIfNeeded(() -> {
update();
}));
notes.addListener((observable, oldValue, newValue) -> {
if (newValue.isCommited()) {
entry.setNotes(newValue.getCurrent());
}
});
}
public void update() {
@ -120,6 +128,7 @@ public class StoreEntryWrapper {
cache.setValue(new HashMap<>(entry.getStoreCache()));
}
color.setValue(entry.getColor());
notes.setValue(new StoreNotes(entry.getNotes(), entry.getNotes()));
busy.setValue(entry.isInRefresh());
deletable.setValue(entry.getConfiguration().isDeletable()

View file

@ -0,0 +1,16 @@
package io.xpipe.app.comp.store;
import lombok.Value;
import java.util.Objects;
@Value
public class StoreNotes {
String commited;
String current;
public boolean isCommited() {
return Objects.equals(commited, current);
}
}

View file

@ -0,0 +1,146 @@
package io.xpipe.app.comp.store;
import atlantafx.base.controls.Popover;
import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.DialogComp;
import io.xpipe.app.comp.base.MarkdownEditorComp;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
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.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;
public class StoreNotesComp extends Comp<StoreNotesComp.Structure> {
private final StoreEntryWrapper wrapper;
public StoreNotesComp(StoreEntryWrapper wrapper) {this.wrapper = wrapper;}
@Override
public Structure createBase() {
var n = wrapper.getNotes();
var button = new IconButtonComp("mdi2n-note-text")
.apply(struc -> AppFont.small(struc.get()))
.focusTraversableForAccessibility()
.tooltipKey("notes")
.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>();
var dialog = new DialogComp() {
@Override
protected void finish() {
n.setValue(new StoreNotes(n.getValue().getCurrent(), n.getValue().getCurrent()));
popover.get().hide();
}
@Override
protected String finishKey() {
return "apply";
}
@Override
public Comp<?> bottom() {
return new ButtonComp(AppI18n.observable("delete"), () -> {
n.setValue(new StoreNotes(null, null));
}).hide(BindingsHelper.map(n, v -> v.getCommited() == null));
}
@Override
protected List<Comp<?>> customButtons() {
return List.of(new ButtonComp(AppI18n.observable("cancel"), () -> {
popover.get().hide();
}));
}
@Override
public Comp<?> content() {
return Comp.of(() -> md.get());
}
}.createRegion();
popover.set(createPopover(dialog));
button.setOnAction(e -> {
if (n.getValue().getCurrent() == null) {
return;
}
if (popover.get().isShowing()) {
e.consume();
return;
}
popover.get().show(button);
e.consume();
});
md.getEditButton().addEventFilter(ActionEvent.ANY, event -> {
if (!popover.get().isDetached()) {
popover.get().setDetached(true);
event.consume();
Platform.runLater(() -> {
Platform.runLater(() -> {
md.getEditButton().fire();
});
});
}
});
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;
}
public record Structure(Popover popover, Button button) implements CompStructure<Button> {
@Override
public Button get() {
return button;
}
}
}

View file

@ -52,7 +52,7 @@ public class ContextualFileReferenceChoiceComp extends Comp<CompStructure<HBox>>
this.fileSystem.setValue(val);
});
this.fileSystem.addListener((observable, oldValue, newValue) -> {
fileSystem.setValue(newValue.get() != null ? newValue.get().ref() : null);
fileSystem.setValue(newValue != null ? newValue.get().ref() : null);
});
this.filePath = filePath;
}

View file

@ -68,6 +68,9 @@ public class DataStoreEntry extends StorageElement {
@Setter
Set<DataStoreEntry> childrenCache = null;
@NonFinal
String notes;
private DataStoreEntry(
Path directory,
UUID uuid,
@ -81,7 +84,8 @@ public class DataStoreEntry extends StorageElement {
Configuration configuration,
JsonNode storePersistentState,
boolean expanded,
DataStoreColor color) {
DataStoreColor color,
String notes) {
super(directory, uuid, name, lastUsed, lastModified, dirty);
this.categoryUuid = categoryUuid;
this.store = DataStorageParser.storeFromNode(storeNode);
@ -94,6 +98,7 @@ public class DataStoreEntry extends StorageElement {
? DataStoreProviders.byStoreClass(store.getClass()).orElse(null)
: null;
this.storePersistentStateNode = storePersistentState;
this.notes = notes;
}
private DataStoreEntry(
@ -152,6 +157,7 @@ public class DataStoreEntry extends StorageElement {
Configuration.defaultConfiguration(),
null,
false,
null,
null);
return entry;
}
@ -168,7 +174,8 @@ public class DataStoreEntry extends StorageElement {
Configuration configuration,
JsonNode storePersistentState,
boolean expanded,
DataStoreColor color) {
DataStoreColor color,
String notes) {
return new DataStoreEntry(
directory,
uuid,
@ -182,7 +189,8 @@ public class DataStoreEntry extends StorageElement {
configuration,
storePersistentState,
expanded,
color);
color,
notes);
}
public static Optional<DataStoreEntry> fromDirectory(Path dir) throws Exception {
@ -191,6 +199,7 @@ public class DataStoreEntry extends StorageElement {
var entryFile = dir.resolve("entry.json");
var storeFile = dir.resolve("store.json");
var stateFile = dir.resolve("state.json");
var notesFile = dir.resolve("notes.md");
if (!Files.exists(entryFile) || !Files.exists(storeFile)) {
return Optional.empty();
}
@ -238,6 +247,14 @@ public class DataStoreEntry extends StorageElement {
})
.orElse(null);
String notes = null;
if (Files.exists(notesFile)) {
notes = Files.readString(notesFile);
}
if (notes != null && notes.isBlank()) {
notes = null;
}
// Store loading is prone to errors.
JsonNode storeNode = null;
try {
@ -256,7 +273,9 @@ public class DataStoreEntry extends StorageElement {
configuration,
persistentState,
expanded,
color));
color,
notes
));
}
@Override
@ -363,6 +382,12 @@ public class DataStoreEntry extends StorageElement {
Files.writeString(directory.resolve("state.json"), stateString);
Files.writeString(directory.resolve("entry.json"), entryString);
Files.writeString(directory.resolve("store.json"), storeString);
var notesFile = directory.resolve("notes.md");
if (Files.exists(notesFile) && notes == null) {
Files.delete(notesFile);
} else {
Files.writeString(notesFile, notes);
}
dirty = false;
}
@ -374,6 +399,14 @@ public class DataStoreEntry extends StorageElement {
}
}
public void setNotes(String newNotes) {
var changed = !Objects.equals(notes, newNotes);
this.notes = newNotes;
if (changed) {
notifyUpdate(false, true);
}
}
public void setColor(DataStoreColor newColor) {
var changed = !Objects.equals(color, newColor);
this.color = newColor;

View file

@ -0,0 +1,157 @@
An h1 header
============
Paragraphs are separated by a blank line.
2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists
look like:
* this one
* that one
* the other one
Note that --- not considering the asterisk --- the actual text
content starts at 4-columns in.
> Block quotes are
> written like so.
>
> They can span multiple paragraphs,
> if you like.
Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all
in chapters 12--14"). Three dots ... will be converted to an ellipsis.
Unicode is supported. ☺
An h2 header
------------
Here's a numbered list:
1. first item
2. second item
3. third item
Note again how the actual text starts at 4 columns in (4 characters
from the left side). Here's a code sample:
# Let me re-iterate ...
for i in 1 .. 10 { do-something(i) }
As you probably guessed, indented 4 spaces. By the way, instead of
indenting the block, you can use delimited blocks, if you like:
~~~
define foobar() {
print "Welcome to flavor country!";
}
~~~
(which makes copying & pasting easier). You can optionally mark the
delimited block for Pandoc to syntax highlight it:
~~~python
import time
# Quick, count to ten!
for i in range(10):
# (but not *too* quick)
time.sleep(0.5)
print i
~~~
### An h3 header ###
Now a nested list:
1. First, get these ingredients:
* carrots
* celery
* lentils
2. Boil some water.
3. Dump everything in the pot and follow
this algorithm:
find wooden spoon
uncover pot
stir
cover pot
balance wooden spoon precariously on pot handle
wait 10 minutes
goto first step (or shut off burner when done)
Do not bump wooden spoon or it will fall.
Notice again how text always lines up on 4-space indents (including
that last line which continues item 3 above).
Here's a link to [a website](http://foo.bar), to a [local
doc](local-doc.html), and to a [section heading in the current
doc](#an-h2-header). Here's a footnote [^1].
[^1]: Footnote text goes here.
Tables can look like this:
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.
***
Here's a definition list:
apples
: Good for making applesauce.
oranges
: Citrus!
tomatoes
: There's no "e" in tomatoe.
Again, text is indented 4 spaces. (Put a blank line between each
term/definition pair to spread things out more.)
Here's a "line block":
| Line one
| Line too
| Line tree
and images can be specified like so:
![example image](example-image.jpg "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:
$$I = \int \rho R^{2} dV$$
And note that you can backslash-escape any punctuation characters
which you wish to be displayed literally, ex.: \`foo\`, \*bar\*, etc.

View file

@ -0,0 +1,31 @@
.popover {
-fx-background-radius: 5;
}
.popover > .content {
-fx-padding: 1;
-fx-background-radius: 5px;
}
.popover > .content > .title > .icon {
-fx-padding: 10 10 0 0;
-fx-background-color: transparent;
}
.popover > .content > .title > .text {
}
.popover > .content > .title > .icon:hover > .graphics * {
-fx-fill: -color-neutral-muted;
}
.popover > .content > .title {
-fx-background-color: -color-bg-subtle;
-fx-background-radius: 5 5 0 0;
-fx-border-width: 0 0 1 0;
-fx-border-color: -color-border-default;
}
.popover > .content > .title > .text {
-fx-padding: 10 0 0 0;
}

View file

@ -1,12 +1,3 @@
.popover {
-fx-background-radius: 0;
}
.popover > .content {
-fx-padding: 10px 0 0 0;
-fx-background-radius: 4px;
}
.store-mini-list-comp > * > * > .content {
-fx-spacing: 0.5em;
}

View file

@ -454,3 +454,6 @@ lockVaultOnHibernationDescription=Når denne funktion er aktiveret, låses Vault
#custom
overview=Oversigt
history=Browsing-historik
skipAll=Spring alle over
notes=Bemærkninger
addNotes=Tilføj noter

View file

@ -448,3 +448,6 @@ lockVaultOnHibernation=Tresor im Ruhezustand des Computers sperren
lockVaultOnHibernationDescription=Wenn diese Funktion aktiviert ist, wird der Tresor automatisch gesperrt, sobald dein Computer in den Ruhezustand versetzt wird. Nach dem Aufwachen musst du deine Tresor-Passphrase erneut eingeben.
overview=Übersicht
history=Browsing-Verlauf
skipAll=Alles überspringen
notes=Anmerkungen
addNotes=Notizen hinzufügen

View file

@ -452,3 +452,5 @@ lockVaultOnHibernationDescription=When enabled, the vault will automatically be
overview=Overview
history=Browsing history
skipAll=Skip all
notes=Notes
addNotes=Add notes

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Bloquear la bóveda al hibernar el ordenador
lockVaultOnHibernationDescription=Si está activada, el almacén se bloqueará automáticamente cuando tu ordenador entre en hibernación/reposo. Al despertarte, tendrás que volver a introducir la contraseña de tu bóveda.
overview=Visión general
history=Historial de navegación
skipAll=Saltar todo
notes=Notas
addNotes=Añadir notas

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Verrouille le coffre-fort lors de l'hibernation de l'ordi
lockVaultOnHibernationDescription=Lorsque cette option est activée, le coffre-fort sera automatiquement verrouillé une fois que ton ordinateur sera mis en hibernation/en veille. Au réveil, tu devras saisir à nouveau la phrase de passe de ton coffre-fort.
overview=Vue d'ensemble
history=Historique de navigation
skipAll=Sauter tout
notes=Notes
addNotes=Ajouter des notes

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Blocca il caveau durante l'ibernazione del computer
lockVaultOnHibernationDescription=Se abilitato, il vault si blocca automaticamente quando il computer viene messo in ibernazione o a riposo. Al risveglio, dovrai inserire nuovamente la passphrase del vault.
overview=Panoramica
history=Cronologia di navigazione
skipAll=Salta tutto
notes=Note
addNotes=Aggiungi note

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=コンピュータのハイバネーション時に保管
lockVaultOnHibernationDescription=有効にすると、コンピュータが休止状態/スリープ状態になると、保管庫は自動的にロックされる。スリープ解除後、保管庫のパスフレーズを再度入力する必要がある。
overview=概要
history=閲覧履歴
skipAll=すべてスキップする
notes=備考
addNotes=メモを追加する

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Kluis op computer in slaapstand
lockVaultOnHibernationDescription=Als deze optie is ingeschakeld, wordt de kluis automatisch vergrendeld zodra je computer in de slaapstand wordt gezet. Als je wakker wordt, moet je je wachtwoordzin voor de kluis opnieuw invoeren.
overview=Overzicht
history=Browsegeschiedenis
skipAll=Alles overslaan
notes=Opmerkingen
addNotes=Opmerkingen toevoegen

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Bloqueia o cofre na hibernação do computador
lockVaultOnHibernationDescription=Quando ativado, a abóbada é automaticamente bloqueada quando o computador é colocado em hibernação/sono. Quando acordares, terás de introduzir novamente a frase-chave do cofre.
overview=Resumo
history=Histórico de navegação
skipAll=Salta tudo
notes=Nota
addNotes=Adiciona notas

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=Блокировка хранилища при спяще
lockVaultOnHibernationDescription=Если эта функция включена, хранилище будет автоматически блокироваться, как только компьютер перейдет в спящий режим. После пробуждения тебе придется снова ввести кодовую фразу хранилища.
overview=Обзор
history=История просмотров
skipAll=Пропустить все
notes=Заметки
addNotes=Добавляй заметки

View file

@ -436,3 +436,6 @@ lockVaultOnHibernation=Bilgisayar hazırda bekletme modunda kasayı kilitleme
lockVaultOnHibernationDescription=Etkinleştirildiğinde, bilgisayarınız hazırda bekletme/uyku moduna geçtiğinde kasa otomatik olarak kilitlenecektir. Uyandığınızda, kasa parolanızı tekrar girmeniz gerekecektir.
overview=Genel Bakış
history=Tarama geçmişi
skipAll=Tümünü atla
notes=Notlar
addNotes=Notlar ekleyin

View file

@ -435,3 +435,6 @@ lockVaultOnHibernation=电脑休眠时锁定保险库
lockVaultOnHibernationDescription=启用后,一旦电脑进入休眠/睡眠状态,保管库就会自动锁定。唤醒后,您必须再次输入保险库密码。
overview=概述
history=浏览历史
skipAll=全部跳过
notes=说明
addNotes=添加注释