1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-08 05:57:02 +09:00

Merge branch 'main' of github.com:anyproto/anytype-ts into feature/JS-6113-space-store-migration

This commit is contained in:
Andrew Simachev 2025-01-31 14:13:08 +01:00
commit ecb1ce153b
No known key found for this signature in database
GPG key ID: 1DFE44B21443F0EF
37 changed files with 211 additions and 119 deletions

View file

@ -261,6 +261,7 @@ class MenuManager {
{ label: Util.translate('electronMenuDebugReconcile'), click: () => Util.send(this.win, 'commandGlobal', 'debugReconcile') },
{ label: Util.translate('electronMenuDebugNet'), click: () => Util.send(this.win, 'commandGlobal', 'debugNet') },
{ label: Util.translate('electronMenuDebugLog'), click: () => Util.send(this.win, 'commandGlobal', 'debugLog') },
{ label: Util.translate('electronMenuDebugProfiler'), click: () => Util.send(this.win, 'commandGlobal', 'debugProfiler') },
Separator,

View file

@ -1 +1 @@
0.39.0-rc08
0.39.2

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "anytype",
"version": "0.44.11-alpha",
"version": "0.44.15-beta",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "anytype",
"version": "0.44.11-alpha",
"version": "0.44.15-beta",
"hasInstallScript": true,
"license": "SEE LICENSE IN LICENSE.md",
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "anytype",
"version": "0.44.11-alpha",
"version": "0.44.15-beta",
"description": "Anytype",
"main": "electron.js",
"scripts": {

View file

@ -247,6 +247,7 @@
"electronMenuDebugReconcile": "Reconcile",
"electronMenuDebugNet": "Network",
"electronMenuDebugLog": "Export log",
"electronMenuDebugProfiler": "Export CPU trace",
"electronMenuClose": "Close Window",
"electronMenuEdit": "Edit",
"electronMenuUndo": "Undo",

View file

@ -24,7 +24,7 @@ export default {
share: 'https://join.anytype.io/',
notionFAQ: 'https://doc.anytype.io/anytype-docs/basics/space/import-export#notion-import-faq',
publishDomain: '%s.org',
publish: 'https://any.coop/%s/',
publish: 'any.coop/%s',
api: '127.0.0.1:31009',
survey: {

View file

@ -25,12 +25,12 @@
.cardContent > .inner { padding: 16px; }
.cover {
position: relative; aspect-ratio: 7/3; background-position: top center; display: flex; align-items: center;
position: relative; aspect-ratio: 16/9; background-position: top center; display: flex; align-items: center;
background-color: var(--color-shape-highlight-medium); width: 100%; justify-content: center; border-radius: 8px 8px 0px 0px; overflow: hidden;
}
.cover {
img { width: 100%; height: 100%; object-fit: cover; }
img { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.mediaVideo { height: 100%; }
.mediaVideo {

View file

@ -9,11 +9,11 @@
.card {
width: 100%; border: 1px solid var(--color-shape-highlight-medium); transition-property: border-color, background; transition-duration: 0.1s;
transition-timing-function: $easeInQuint; border-radius: 8px; display: inline-block; background: var(--color-bg-primary);
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05); min-height: 72px; position: relative; overflow: hidden;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05); min-height: 72px; position: relative;
}
.card.add { box-shadow: 0px 0px; }
.card.add::after {
.card.add::before {
content: ''; position: absolute; left: 50%; top: 50%; width: 20px; height: 20px; background-image: url('~img/icon/plus/menu0.svg'); margin: -10px 0px 0px -10px;
}

View file

@ -98,6 +98,7 @@
.full, .c100 { width: 100%; }
.half, .c50 { width: 50%; }
.c40 { width: 40%; }
.c60 { width: 60%; }
.c70 { width: 70%; }
.screen { box-shadow: 0px 0px 25px rgba(0,0,0,0.2); }
@ -271,4 +272,4 @@
&.withIconAndCover {
.controlButtons { left: 0px !important; }
}
}
}

View file

@ -2,7 +2,7 @@
.toast {
position: fixed; left: 0px; top: 0px; border-radius: 8px; background: var(--color-control-accent); padding: 11px 16px; text-transform: none;
@include text-common; color: var(--color-bg-primary); display: none; z-index: 1000; white-space: nowrap; transition-duration: 0.25s;
@include text-common; color: var(--color-bg-primary); display: none; z-index: 2000; white-space: nowrap; transition-duration: 0.25s;
transition-property: opacity, transform; transition-timing-function: cubic-bezier(0.34, 1.56, 0.64, 1); max-width: 50%;
}

View file

@ -20,6 +20,20 @@
.value { display: flex; flex-direction: row; align-items: center; justify-content: flex-end; flex-shrink: 0; }
}
.urlWrapper { display: flex; flex-direction: row; align-items: center; gap: 0px 8px; }
.urlWrapper {
.label { flex-grow: 1; user-select: text !important; position: relative; @include text-overflow-nw; }
.label::after {
content: ''; display: block; position: absolute; right: -22px; top: 0px; width: 46px; height: 100%; z-index: 1;
background: linear-gradient(90deg, rgba(255, 255, 255, 0) -22.83%, var(--color-bg-primary) 34.78%);
}
.button {
flex-shrink: 0; font-weight: 500; @include text-small; color: var(--color-text-primary); height: 18px; padding: 0px 4px;
border-radius: 4px; transition: $transitionAllCommon;
}
.button:hover { background-color: var(--color-shape-highlight-medium) !important; }
}
.buttons { display: flex; flex-direction: row; align-items: center; gap: 0px 8px; justify-content: space-evenly; height: 36px; }
.buttons {
.button { flex-grow: 1; width: 100%; }
@ -27,7 +41,7 @@
.label { color: var(--color-text-secondary); }
}
.error { margin: 0px; }
.error { margin: 0px; text-align: center; }
.outer {
position: absolute; left: 0px; bottom: 0px; transform: translateY(calc(100% + 8px)); width: 100%; box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.2);

View file

@ -18,10 +18,14 @@
.side.right { flex-shrink: 0; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 0px 4px; }
.side.right {
.icon { width: 24px !important; height: 24px !important; flex-shrink: 0; }
.icon { width: 24px !important; height: 24px !important; flex-shrink: 0; border-radius: 4px; }
.icon.search { background-image: url('~img/icon/widget/button/search.svg'); }
.plusWrapper { border-radius: 4px; }
.plusWrapper:hover { background-color: var(--color-shape-highlight-medium); }
.icon.plus { background-image: url('~img/icon/widget/button/plus.svg'); }
.icon.arrow { background-image: url('~img/icon/widget/button/arrow.svg'); }
.icon.arrow { width: 20px !important; background-image: url('~img/icon/widget/button/arrow.svg'); }
}
}

View file

@ -617,10 +617,6 @@ const BlockChat = observer(class BlockChat extends React.Component<I.BlockCompon
};
onReplyClick (e: React.MouseEvent, item: any) {
if (!S.Common.config.experimental) {
return;
};
this.isLoaded = false;
this.setIsBottom(false);

View file

@ -1487,7 +1487,7 @@ const EditorPage = observer(class EditorPage extends React.Component<Props, Stat
};
menuCheck () {
return S.Menu.isOpen('', '', [ 'blockContext', 'searchText', 'onboarding' ]);
return S.Menu.isOpen('', '', [ 'blockContext', 'searchText', 'onboarding', 'publish' ]);
};
onArrowVertical (e: any, pressed: string, range: I.TextRange, length: number, props: any) {

View file

@ -16,7 +16,7 @@ const HeaderMainObject = observer(forwardRef<{}, I.HeaderComponent>((props, ref)
const isLocked = root ? root.isLocked() : false;
const isTypeOrRelation = U.Object.isTypeOrRelationLayout(object.layout);
const isDate = U.Object.isDateLayout(object.layout);
const showShare = S.Block.isAllowed(object.restrictions, [ I.RestrictionObject.Publish ], true) && config.experimental && !isDeleted;
const showShare = S.Block.isAllowed(object.restrictions, [ I.RestrictionObject.Publish ], true) && !isDeleted;
const showRelations = !isTypeOrRelation && !isDate && !isDeleted;
const showMenu = !isTypeOrRelation && !isDeleted;
const cmd = keyboard.cmdSymbol();

View file

@ -5,7 +5,7 @@ import arrayMove from 'array-move';
import { AutoSizer, CellMeasurer, InfiniteLoader, List as VList, CellMeasurerCache } from 'react-virtualized';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { Icon, Switch } from 'Component';
import { I, C, S, J, Relation, keyboard, Dataview, translate } from 'Lib';
import { I, C, S, J, Relation, keyboard, Dataview, translate, analytics } from 'Lib';
const HEIGHT = 28;
const LIMIT = 20;
@ -288,7 +288,6 @@ const MenuRelationList = observer(class MenuRelationList extends React.Component
};
onSortEnd (result: any) {
const { config } = S.Common;
const { oldIndex, newIndex } = result;
const { param } = this.props;
const { data } = param;
@ -305,8 +304,12 @@ const MenuRelationList = observer(class MenuRelationList extends React.Component
const { data } = param;
const { rootId, blockId, getView } = data;
const view = getView();
const object = S.Detail.get(rootId, rootId);
const relation = S.Record.getRelationByKey(item.relationKey);
C.BlockDataviewViewRelationReplace(rootId, blockId, view.id, item.relationKey, { ...item, isVisible: v });
analytics.event('ShowDataviewRelation', { type: v ? 'True' : 'False', relationKey: item.relationKey, format: relation.format, objectType: object.type });
};
onScroll ({ scrollTop }) {

View file

@ -58,10 +58,10 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
const onPublish = (isUpdate?: boolean) => {
const analyticsName = isUpdate ? 'ShareObjectUpdate' : 'ShareObjectPublish';
publishRef.current.setLoading(true);
publishRef.current?.setLoading(true);
C.PublishingCreate(S.Common.space, rootId, slug, joinRef.current?.getValue(), (message: any) => {
publishRef.current.setLoading(false);
publishRef.current?.setLoading(false);
if (message.error.code) {
setError(message.error.description);
@ -80,10 +80,10 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
};
const onUnpublish = () => {
unpublishRef.current.setLoading(true);
unpublishRef.current?.setLoading(true);
C.PublishingRemove(S.Common.space, rootId, (message: any) => {
unpublishRef.current.setLoading(false);
unpublishRef.current?.setLoading(false);
if (message.error.code) {
setError(message.error.description);
@ -138,13 +138,12 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
};
const setSlugHander = v => setSlug(U.Common.slug(v));
const onUrlClick = () => Action.openUrl(url);
let buttons = [];
if (isStatusLoaded && isOnline) {
if (status === null) {
buttons.push({ text: translate('menuPublishButtonPublish'), ref: publishRef, onClick: onPublish });
buttons.push({ text: translate('menuPublishButtonPublish'), ref: publishRef, onClick: () => onPublish() });
} else {
buttons = buttons.concat([
{ text: translate('menuPublishButtonUnpublish'), color: 'blank', ref: unpublishRef, onClick: onUnpublish },
@ -186,7 +185,15 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
onChange={(e, v) => setSlugHander(v)}
maxLength={300}
/>
<Label className="small" text={url} onClick={onUrlClick} />
<div className="urlWrapper">
<Label className="small" text={url} />
<Button
color="blank"
className="simple"
text={translate('commonCopy')}
onClick={() => U.Common.copyToast(translate('commonLink'), `https://${url}`)}
/>
</div>
{space.isShared ? (
<div className="flex">

View file

@ -150,7 +150,7 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
const ret = (isPopup ? matchPopup : match) || { params: {} };
// Universal object route
if (pathname.match('/object')) {
if (pathname.match(/^\/object/)) {
ret.params.page = 'main';
ret.params.action = 'object';
ret.params.id = data.objectId;
@ -160,13 +160,13 @@ const Page = observer(class Page extends React.Component<I.PageComponent> {
};
// Invite route
if (pathname.match('/invite')) {
if (pathname.match(/^\/invite/)) {
ret.params.page = 'main';
ret.params.action = 'invite';
};
// Membership route
if (pathname.match('/membership')) {
if (pathname.match(/^\/membership/)) {
ret.params.page = 'main';
ret.params.action = 'membership';
};

View file

@ -43,7 +43,7 @@ const PageMainChat = observer(forwardRef<{}, I.PageComponent>((props, ref) => {
return;
};
headerRef.current.forceUpdate();
headerRef.current?.forceUpdate();
resize();
});
};

View file

@ -1,6 +1,6 @@
import * as React from 'react';
import { Title, Label, IconObject, Button } from 'Component';
import { I, C, S, U, translate, Renderer, analytics } from 'Lib';
import { I, C, S, U, translate, analytics, Action } from 'Lib';
import { observer } from 'mobx-react';
interface State {
@ -25,7 +25,6 @@ const PopupSettingsPageDataIndex = observer(class PopupSettingsPageDataIndex ext
};
render () {
const { config } = S.Common;
const { onPage } = this.props;
const { list } = this.state;
const { dataPath, spaceStorage } = S.Common;
@ -54,21 +53,19 @@ const PopupSettingsPageDataIndex = observer(class PopupSettingsPageDataIndex ext
</div>
</div>
{config.experimental ? (
<div className="item">
<div className="side left">
<IconObject object={{ iconEmoji: ':earth_americas:' }} size={44} />
<div className="item">
<div className="side left">
<IconObject object={{ iconEmoji: ':earth_americas:' }} size={44} />
<div className="txt">
<Title text={translate('popupSettingsDataManagementDataPublishTitle')} />
<Label text={size} />
</div>
</div>
<div className="side right">
<Button color="blank" className="c28" text={translate(`commonManage`)} onClick={() => onPage('dataPublish')} />
<div className="txt">
<Title text={translate('popupSettingsDataManagementDataPublishTitle')} />
<Label text={size} />
</div>
</div>
) : ''}
<div className="side right">
<Button color="blank" className="c28" text={translate(`commonManage`)} onClick={() => onPage('dataPublish')} />
</div>
</div>
<div className="item">
<div className="side left">
@ -93,7 +90,7 @@ const PopupSettingsPageDataIndex = observer(class PopupSettingsPageDataIndex ext
};
componentDidMount(): void {
C.PublishingList(S.Common.space, (message: any) => {
C.PublishingList('', (message: any) => {
if (!message.error.code) {
this.setState({ list: message.list });
};
@ -141,7 +138,7 @@ const PopupSettingsPageDataIndex = observer(class PopupSettingsPageDataIndex ext
};
onOpenDataLocation () {
Renderer.send('openPath', S.Common.dataPath);
Action.openPath(S.Common.dataPath);
analytics.event('ClickSettingsDataManagementLocation', { route: analytics.route.settings });
};

View file

@ -21,7 +21,7 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
const { list } = this.state;
const Row = (item: any) => {
const object = S.Detail.get(SUB_ID, item.objectId);
const object = S.Detail.mapper(item.details);
return (
<div className="row">
@ -65,18 +65,9 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
};
load () {
C.PublishingList(S.Common.space, (message: any) => {
C.PublishingList('', (message: any) => {
if (!message.error.code) {
const list = message.list;
const ids = list.map(item => item.objectId);
U.Data.subscribeIds({
subId: SUB_ID,
ids,
noDeps: true,
}, () => {
this.setState({ list });
});
this.setState({ list: message.list });
};
});
};
@ -88,6 +79,7 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
onMore (item: any) {
const { getId } = this.props;
const element = $(`#${getId()} #icon-more-${item.objectId}`);
const object = S.Detail.mapper(item.details);
const options: any[] = [
{ id: 'open', name: translate('menuPublishButtonOpen') },
{ isDiv: true },
@ -108,7 +100,7 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
onSelect: (e: any, element: any) => {
switch (element.id) {
case 'open': {
U.Object.openAuto(S.Detail.get(SUB_ID, item.objectId));
U.Object.openAuto(object);
break;
};
@ -133,7 +125,7 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
};
onUnpublish (item: any) {
const object = S.Detail.get(SUB_ID, item.objectId);
const object = S.Detail.mapper(item.details);
C.PublishingRemove(S.Common.space, item.objectId, (message: any) => {
if (!message.error.code) {

View file

@ -84,7 +84,7 @@ const PopupSettingsSpaceShare = observer(class PopupSettingsSpaceShare extends R
};
const Member = (item: any) => {
const isCurrent = item.id == participant.id;
const isCurrent = item.id == participant?.id;
let tag = null;
let button = null;

View file

@ -436,6 +436,12 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
this.onClick(e, item);
};
});
keyboard.shortcut(`${cmd}+n`, e, () => {
e.preventDefault();
this.pageCreate(filter);
})
};
onArrow (dir: number) {
@ -775,6 +781,10 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
});
};
pageCreate (name: string) {
keyboard.pageCreate({ name }, analytics.route.search, [ I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
};
filterMapper (it: any, config: any) {
return !(it.isHidden && !config.debug.hiddenObject);
};
@ -834,7 +844,7 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
} else {
switch (item.id) {
case 'add': {
keyboard.pageCreate({ name: filter }, 'Search', [ I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
this.pageCreate(filter)
break;
};

View file

@ -128,7 +128,7 @@ const PopupSettingsOnboarding = observer(class PopupSettingsOnboarding extends R
};
onUpload () {
Action.openFileDialog({ extensions: [ 'yml' ] }, (paths: string[]) => this.onChange('path', paths[0]));
Action.openFileDialog({ extensions: [ 'yml', 'yaml' ] }, (paths: string[]) => this.onChange('path', paths[0]));
};
onSave () {
@ -180,7 +180,7 @@ const PopupSettingsOnboarding = observer(class PopupSettingsOnboarding extends R
onPathClick (path: string) {
if (path) {
Renderer.send('openPath', U.Common.getElectron().dirName(path));
Action.openPath(U.Common.getElectron().dirName(path));
};
};
@ -226,10 +226,9 @@ const PopupSettingsOnboarding = observer(class PopupSettingsOnboarding extends R
};
onTooltipShow (e: any, text: string) {
if (!text) {
return;
if (text) {
Preview.tooltipShow({ text, element: $(e.currentTarget) });
};
Preview.tooltipShow({ text, element: $(e.currentTarget) });
};
onTooltipHide () {

View file

@ -45,6 +45,7 @@ const Sidebar = observer(class Sidebar extends React.Component<{}, State> {
};
render() {
const { showVault } = S.Common;
const page = this.state.page || 'widget';
const cmd = keyboard.cmdSymbol();
const Component = Components[page];
@ -98,13 +99,8 @@ const Sidebar = observer(class Sidebar extends React.Component<{}, State> {
const node = $(this.node);
const vault = $(S.Common.getRef('vault').node);
if (showVault) {
node.addClass('withVault');
vault.removeClass('isHidden');
} else {
node.removeClass('withVault');
vault.addClass('isHidden');
};
node.toggleClass('withVault', showVault);
vault.toggleClass('isHidden', !showVault);
};
setActive (id: string): void {

View file

@ -1,17 +1,20 @@
import React, { forwardRef, MouseEvent } from 'react';
import React, { forwardRef, useRef, MouseEvent } from 'react';
import { observer } from 'mobx-react';
import { Icon, IconObject, ObjectName } from 'Component';
import { I, S, U, C, J, translate, sidebar, keyboard, analytics, Storage, Action } from 'Lib';
import { I, S, U, C, J, translate, sidebar, keyboard, analytics, Storage, Action, Preview } from 'Lib';
const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
const { parent } = props;
const space = U.Space.getSpaceview();
const plusRef = useRef(null);
const participants = U.Space.getParticipantsList([ I.ParticipantStatus.Active, I.ParticipantStatus.Joining, I.ParticipantStatus.Removing ]);
const requestCnt = participants.filter(it => it.isJoining || it.isRemoving).length;
const isSpaceOwner = U.Space.isMyOwner();
const canWrite = U.Space.canMyParticipantWrite();
const cn = [ 'body' ];
const cmd = keyboard.cmdSymbol();
const alt = keyboard.altSymbol();
const buttons = [
space.chatId && U.Object.isAllowedChat() ? { id: 'chat', name: translate('commonMainChat') } : null,
space.isShared ? { id: 'member', name: translate('commonMembers') } : null,
@ -248,6 +251,12 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
};
};
const onPlusHover = (e: MouseEvent) => {
const t = Preview.tooltipCaption(translate('commonCreateNewObject'), `${cmd} + N / ${cmd} + ${alt} + N`);
Preview.tooltipShow({ text: t, element: $(plusRef.current) });
};
return (
<div
className={cn.join(' ')}
@ -268,8 +277,13 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
</div>
<div className="side right">
<Icon className="search withBackground" onClick={onSearch} tooltip={translate('commonSearch')} tooltipCaption={`${cmd} + S`} />
<Icon className="plus withBackground" onClick={onCreate} tooltip={translate('commonCreateNewObject')} tooltipCaption={`${cmd} + N`} />
<Icon id={`widget-${parent.id}-arrow`} className="arrow withBackground" onClick={onArrow} tooltip={translate('commonSelectType')} />
{canWrite ? (
<div className="plusWrapper" onMouseEnter={onPlusHover} onMouseLeave={() => Preview.tooltipHide()}>
<Icon ref={plusRef} className="plus withBackground" onClick={onCreate} />
<Icon id={`widget-${parent.id}-arrow`} className="arrow withBackground" onClick={onArrow} />
</div>
) : ''}
</div>
</div>

View file

@ -22,51 +22,70 @@ export default [
//{ type: I.BlockType.IconPage, icon: '🎄' },
title(`Desktop 0.45.0 Released!`),
text('We are really excited to announce such a big update to Anytype, bringing important features that have been several months in the making features that many of you have been asking for a long time: Web Publishing, Raycast extension and RTL support. As you explore them, please kindly note that they represent the huge step toward a more powerful Anytype. Well be enriching these experiences with more features in the coming months, so your feedback is, as always, warmly welcomed.'),
text('Hello Anytypers! Were excited to share a major update youve been eagerly awaiting. Version 0.45.0 introduces Web Publishing, a Raycast extension, RTL support, and a host of quality-of-life improvements — all inspired by your requests and feedback. Thank you for helping us shape Anytype into a friendlier, more powerful tool for everyone.'),
text(''),
h2(`Highlights`),
h3(`Redesigned Space Panel & Navigation`),
text(`The left sidebar now functions as a navigation panel, as a Space Panel. It serves as a hub for quick and compact access to the main space controls, provides easy navigation to its contents, and is visually distinct from the customisable widgets. You can also view the synchronization status of the space here.`),
text(`For even quicker access, or if the sidebar is hidden, use ${hl(`${cmd} + S`)} to open the Global Search and ${hl(`${cmd} + N`)} to create a new Object.`),
text(`Weve relocated the navigation controls to the Space Panel for a smoother experience. You can now navigate back and forth, search for Objects, and create new ones from a familiar place.`),
text(`Pro tip: if your sidebar is hidden, press ${hl(`${cmd} + S`)} to open Global Search or ${hl(`${cmd} + N`)} to create a new Object.`),
img(`45/1.png`),
text(``),
h3(`Web Publishing`),
text(`One of the most requested features is finally here: the ability to publish Objects as static pages available on the web (HTTPS links). The published Object will be uploaded to our server and accessible via the URL as an unencrypted HTML page. If you have an any-name, your pages will be published on your personal subdomain.`),
text(`<b>Note:</b> Linked objects and some blocks such as Sets, Collections and Relations are not supported at this stage. More enhancements along with multi-page support will be implemented in the future to cover more use cases.`),
text(`You can now publish Objects as static web pages (HTTPS links) on your personal subdomain if you have *any name. These pages are uploaded to our servers as unencrypted HTML files.`),
text(`This is an early version — mobile optimization, linked Objects, and blocks like Sets, Collections and Relations arent supported yet. Multi-page publishing and other enhancements are on the way, and wed love your feedback to guide these improvements.`),
img(`45/2.png`),
text(``),
h3(`Raycast Extension (macOS)`),
text(`The first implementation based on our local API, currently in prototype form and not yet open. Raycast integration v1 works via local endpoint, which supports a limited amount of operations (create, read, delete) for spaces, objects, types, and allows you to search across spaces.`),
text(`Right now, the extension is available only for Mac users, but we plan to release an open API with use cases such as Bulk Import and Export, NoCode tools and integrations in the future.`),
text(`Our long-awaited API is beginning to take shape! The first step is Raycast integration, allowing you to create, read, and delete Spaces, Objects, and Types, as well as search across them, all from Raycast on macOS.`),
text(`While this initial version focuses on a basic set of features, were laying the groundwork for an open API that will eventually support bulk import and export, NoCode tools, and more integrations. Were excited to see what youll build!`),
text(`${link('https://www.raycast.com/any/anytype', 'Install the Raycast Extension here')}`),
img(`45/3.png`),
text(``),
h3(`RTL Support`),
text(`Introducing Right-to-Left language support. Since this is our first implementation, we are looking forward to your testing and feedback to help address any specific cases requiring further adjustments.`),
text(`Were happy to introduce right-to-left language support! This first iteration might need some extra polish, so your feedback is invaluable. Let us know what works and what needs a bit more attention.`),
video(`45/4.mp4`),
text(``),
h2(`Quality-of-Life`),
bullet(`Added a new option to add existing Objects to Collection, available in the updated arrow menu alongside other content-related settings.`),
img(`45/5.png`, `c60`),
text(``),
h3(`Add Existing Objects to a Collection`),
text(`Weve added an option to add existing Objects into a Collection. Look for it in the updated arrow menu alongside other content settings.`),
img(`45/5.png`, `c50`),
text(``),
bullet(`Horizontal alignment has been added to the Grid layout: each column can be set to align left, center or right.`),
h3(`Horizontal Alignment in Grid Layout`),
text(`Columns in the Grid layout can now be aligned left, center, or right.`),
img(`45/6.png`, `c60`),
text(``),
bullet(`Updated Widget Settings menu: removed the ability to change widget source and ${hl('Edit Widgets')} action. The appearance section now contains only options to change widget view (Compact List, List, View, Link) and the number of objects has been moved to a separate section.`),
img(`45/7.png`, `c60`),
h3(`Simplified Widget Settings Menu`),
bullet(`Appearance options are now limited to changing the widgets view (Compact List, List, View, Link).`),
bullet(`The "Number of Objects" setting has moved to its own section.`),
img(`45/7.png`, `c40`),
text(``),
bullet(`Diagrams in the Kroki embed block support links. Thanks, @${link('https://community.anytype.io/t/kroki-links-are-not-usable/25543', 'siousu')}!`),
bullet(`Updated the color of text selection in dark mode to improve visibility. Thanks, @${link('https://community.anytype.io/t/selected-text-background-color-on-a-given-object-heavily-dependent-on-monitor-settings/25509', 'kermit_frog')}!`),
bullet(`Inline Set header adapts to resizing, preventing controls from overlapping a block next to it.`),
bullet(`Images copied from the Safari browser (macOS) are now pasted into the object editor as files, not URLs.`),
bullet(`The QR code appearance has been standardized.`),
h3(`Clickable Links in Kroki Diagrams`),
text(`Kroki embed blocks now support links within diagrams. Thanks to @${link('https://community.anytype.io/t/kroki-links-are-not-usable/25543', 'siousu')} for the suggestion!`),
text(``),
h3(`Improved Dark Mode Text Selection`),
text(`We tweaked the selection color for better visibility. Shout-out to @${link('https://community.anytype.io/t/selected-text-background-color-on-a-given-object-heavily-dependent-on-monitor-settings/25509', 'kermit_frog')} for flagging this!`),
text(``),
h3(`Inline Set Header Resize Adjustments`),
text(`Inline Set headers now adapt when resizing to keep controls from overlapping neighboring blocks.`),
text(``),
h3(`Better Image Pasting on macOS Safari`),
text(`Images copied from Safari will now paste into the object editor as files instead of URLs.`),
text(``),
h3(`Standardized QR Code Appearance`),
text(`All QR codes in Anytype now follow a consistent style.`),
text(``),
h2(`Bug Fixes`),
@ -75,7 +94,7 @@ export default [
bullet(`Dragging headers in the Grid to rearrange columns no longer highlights the text of other headers. Thanks, @${link('https://community.anytype.io/t/moving-column-headers-in-the-grid-to-swap-columns-selects-all-headers/26100', 'Code-Jack')}!`),
bullet(`Fixed keyboard navigation in the Command menu. Thanks, @${link('https://community.anytype.io/t/adding-a-link-cursor-jumps-too-deep-in-the-selection-box/25763', 'Code-Jack')}!`),
bullet(`Bin Search works correctly, without causing Objects to be filtered out.`),
bullet(`Relations containing angle brackets (e.g., <abc>) are saved correctly. Thanks, @${link('https://community.anytype.io/t/angle-brackets-in-relation-will-disappear-when-clicking-it/25534', 'CoolGuy')}!`),
bullet(`Relations containing angle brackets (e.g., ${hl('&lt;abc&gt;')}) are saved correctly. Thanks, @${link('https://community.anytype.io/t/angle-brackets-in-relation-will-disappear-when-clicking-it/25534', 'CoolGuy')}!`),
bullet(`Input to Date type relations works correctly. Thanks, @${link('https://community.anytype.io/t/date-entry-not-working/26112', 'flypenguin')}!`),
bullet(`Removed the option to paste YouTube channel links as Embed. Thanks, @${link('https://community.anytype.io/t/pasting-a-link-to-an-yt-channel-paste-as-embed-shouldnt-appear/26297', 'Code-Jack')}!`),
bullet(`Fixed an issue where pasting with all blocks selected in the object editor would wipe out content without pasting from the clipboard. Thanks, @${link('https://community.anytype.io/t/pasting-when-all-blocks-in-the-object-editor-are-selected-will-wipe-out-everything-but-will-not-paste-whats-in-the-clipboard/25040', 'sky1')}!`),

View file

@ -11,4 +11,5 @@ export interface PublishState {
version: string;
timestamp: number;
size: number;
details: any;
};

View file

@ -221,10 +221,8 @@ class Action {
};
C.FileDownload(id, U.Common.getElectron().tmpPath, (message: any) => {
if (message.path) {
Renderer.send('openPath', message.path);
analytics.event('OpenMedia', { route });
};
this.openPath(message.path);
analytics.event('OpenMedia', { route });
});
};
@ -554,7 +552,7 @@ class Action {
return;
};
Renderer.send('openPath', paths[0]);
this.openPath(paths[0]);
analytics.event('Export', { type, middleTime: message.middleTime, route });
if (callBack) {

View file

@ -377,6 +377,7 @@ class Analytics {
break;
};
case 'ShowDataviewRelation':
case 'DeleteRelationValue':
case 'ChangeRelationValue':
case 'FeatureRelation':

View file

@ -1958,7 +1958,15 @@ export const DebugExportLog = (path: string, callBack?: (message: any) => void)
request.setDir(path);
dispatcher.request(DebugExportLog.name, request, callBack);
}
};
export const DebugRunProfiler = (duration: number, callBack?: (message: any) => void) => {
const request = new Rpc.Debug.RunProfiler.Request();
request.setDurationinseconds(duration);
dispatcher.request(DebugRunProfiler.name, request, callBack);
};
// ---------------------- NOTIFICATION ---------------------- //

View file

@ -5,7 +5,7 @@ import { observable, set } from 'mobx';
import Commands from 'dist/lib/pb/protos/commands_pb';
import Events from 'dist/lib/pb/protos/events_pb';
import Service from 'dist/lib/pb/protos/service/service_grpc_web_pb';
import { I, M, S, U, J, translate, analytics, Renderer, Action, Dataview, Mapper, Storage, keyboard } from 'Lib';
import { I, M, S, U, J, analytics, Renderer, Action, Dataview, Mapper, keyboard } from 'Lib';
import * as Response from './response';
import { ClientReadableStream } from 'grpc-web';

View file

@ -691,6 +691,7 @@ export const Mapper = {
version: obj.getVersion(),
timestamp: obj.getTimestamp(),
size: obj.getSize(),
details: Decode.struct(obj.getDetails()),
};
},

View file

@ -62,6 +62,12 @@ export const DebugNetCheck = (response: Rpc.Debug.NetCheck.Response) => {
};
};
export const DebugRunProfiler = (response: Rpc.Debug.RunProfiler.Response) => {
return {
path: response.getPath(),
};
};
export const Export = (response: any) => {
return {
path: response.getPath(),

View file

@ -237,6 +237,11 @@ class Keyboard {
$('#button-header-relation').trigger('click');
});
// Select type
this.shortcut(`${cmd}+alt+n`, e, () => {
$('#widget-space #widget-space-arrow').trigger('click');
});
// Switch dark/light mode
this.shortcut(`${cmd}+shift+m`, e, () => {
Action.themeSet(!theme ? 'dark' : '');
@ -266,10 +271,12 @@ class Keyboard {
if (canWrite) {
// Create new page
this.shortcut(`${cmd}+n`, e, () => {
e.preventDefault();
this.pageCreate({}, analytics.route.shortcut, [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
});
if (!S.Popup.isOpen('search')) {
this.shortcut(`${cmd}+n`, e, () => {
e.preventDefault();
this.pageCreate({}, analytics.route.shortcut, [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
});
};
// Lock/Unlock
this.shortcut(`ctrl+shift+l`, e, () => {
@ -525,7 +532,7 @@ class Keyboard {
return;
};
Renderer.send('openPath', paths[0]);
Action.openPath(paths[0]);
});
});
break;
@ -535,7 +542,7 @@ class Keyboard {
Action.openDirectoryDialog({ buttonLabel: translate('commonExport') }, paths => {
C.DebugExportLocalstore(paths[0], [], (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', paths[0]);
Action.openPath(paths[0]);
};
});
});
@ -546,7 +553,7 @@ class Keyboard {
C.DebugSpaceSummary(S.Common.space, (message: any) => {
if (!message.error.code) {
U.Common.getElectron().fileWrite('debug-space-summary.json', JSON.stringify(message, null, 5), { encoding: 'utf8' });
Renderer.send('openPath', tmpPath);
Action.openPath(tmpPath);
};
});
break;
@ -556,7 +563,7 @@ class Keyboard {
C.DebugStat((message: any) => {
if (!message.error.code) {
U.Common.getElectron().fileWrite('debug-stat.json', JSON.stringify(message, null, 5), { encoding: 'utf8' });
Renderer.send('openPath', tmpPath);
Action.openPath(tmpPath);
};
});
break;
@ -565,7 +572,7 @@ class Keyboard {
case 'debugTree': {
C.DebugTree(rootId, logPath, false, (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', logPath);
Action.openPath(logPath);
};
});
break;
@ -574,7 +581,7 @@ class Keyboard {
case 'debugProcess': {
C.DebugStackGoroutines(logPath, (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', logPath);
Action.openPath(logPath);
};
});
break;
@ -625,7 +632,16 @@ class Keyboard {
case 'debugLog': {
C.DebugExportLog(tmpPath, (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', tmpPath);
Action.openPath(tmpPath);
};
});
break;
};
case 'debugProfiler': {
C.DebugRunProfiler(30, (message: any) => {
if (!message.error.code) {
Action.openPath(message.path);
};
});
break;

View file

@ -132,6 +132,13 @@ class Preview {
window.clearTimeout(this.timeout.delay);
this.timeout.delay = window.setTimeout(() => this.delayTooltip = delay, 500);
this.delayTooltip = 100;
win.off('click.tooltip').on('click.tooltip', () => {
this.tooltipHide(true);
win.off('click.tooltip');
});
}, this.delayTooltip);
};

View file

@ -580,7 +580,7 @@ class UtilCommon {
onConfirm: () => {
C.DebugTree(rootId, logPath, false, (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', logPath);
Action.openPath(logPath);
};
});