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

Update logic

This commit is contained in:
Andrew Simachev 2025-01-31 11:43:02 +01:00
commit 38af4e99ba
No known key found for this signature in database
GPG key ID: 1DFE44B21443F0EF
60 changed files with 1629 additions and 240 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

@ -151,13 +151,15 @@ class WindowManager {
x: Math.floor(width / 2 - 212),
y: Math.floor(height - 282),
titleBarStyle: 'hidden',
alwaysOnTop: true,
focusable: true,
skipTaskbar: true,
});
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'challenge', `index.html`));
win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
win.loadURL('file://' + path.join(Util.appPath, 'dist', 'challenge', 'index.html'));
win.setMenu(null);
is.windows || is.linux ? win.showInactive() : win.show();
win.focus();
win.showInactive(); // show inactive to prevent focus loose from other app
win.webContents.once('did-finish-load', () => {
win.webContents.postMessage('challenge', options);

View file

@ -40,7 +40,7 @@ window.AnytypeGlobalConfig = {
emojiUrl: J.Extension.clipper.emojiUrl,
menuBorderTop: 16,
menuBorderBottom: 16,
flagsMw: {},
flagsMw: { request: true },
};
let rootId = '';

View file

@ -66,6 +66,8 @@ const Index = observer(class Index extends React.Component<I.PageComponent, Stat
login () {
const appKey = Storage.get('appKey');
console.log('appKey', appKey);
if (appKey) {
Util.authorize(appKey, () => {
const { serverPort, gatewayPort } = S.Extension;

View file

@ -1 +1 @@
0.39.0-rc07
0.39.2

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "anytype",
"version": "0.44.10-alpha",
"version": "0.44.15-beta",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "anytype",
"version": "0.44.10-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.10-alpha",
"version": "0.44.15-beta",
"description": "Anytype",
"main": "electron.js",
"scripts": {

View file

@ -102,6 +102,8 @@ export default {
'sourceObject',
'uniqueKey',
'defaultTemplateId',
'defaulTypeId',
'defaultVewType',
'layoutAlign',
'layoutWidth',
],

View file

@ -249,6 +249,7 @@
"electronMenuDebugReconcile": "Reconcile",
"electronMenuDebugNet": "Network",
"electronMenuDebugLog": "Export log",
"electronMenuDebugProfiler": "Export CPU trace",
"electronMenuClose": "Close Window",
"electronMenuEdit": "Edit",
"electronMenuUndo": "Undo",
@ -1626,11 +1627,14 @@
"menuSyncStatusEmpty": "There are no objects to show",
"menuPublishTitle": "Publish to web",
"menuPublishInfoTooltip": "Published object will be uploaded to our publishing server and will be accessible via the URL as a static, unencrypted HTML page. Linked objects will not be published. Currently, not all blocks are supported for publishing, such as sets, collections, and relations.",
"menuPublishInfoTooltip": "Published object will be uploaded to our publishing server and will be accessible via the URL as a static, unencrypted HTML page. Linked objects will not be published.<br/>Currently, not all blocks are supported for publishing, such as sets, collections, and relations.",
"menuPublishLabelJoin": "Join Space Button",
"menuPublishButtonPublish": "Publish",
"menuPublishButtonUnpublish": "Unpublish",
"menuPublishButtonUpdate": "Update",
"menuPublishButtonView": "View in Browser",
"menuPublishButtonOpen": "Open Object",
"menuPublishButtonCopy": "Copy Web Link",
"menuPublishLabelOffline": "No internet connection",
"previewEdit": "Edit Link",
@ -2165,6 +2169,8 @@
"errorSpaceMakeShareable103": "Oops! The request failed. Please check your Internet connection and try again.",
"errorSpaceMakeShareable104": "Limit reached for this space. Please upgrade your membership or contact support for assistance.",
"errorPublishingCreate103": "Looks like some files are over 100 MB. Please remove or slim them down and try again.",
"errorIncorrectEmail": "Incorrect E-mail",
"origin0": "Empty",
@ -2176,6 +2182,7 @@
"origin6": "Use case",
"origin7": "Library installed",
"origin8": "Bookmark",
"origin9": "API",
"emojiCategoryPeople": "Smileys & People",
"emojiCategoryNature": "Animals & Nature",

View file

@ -23,8 +23,9 @@ export default {
invite: 'https://invite.any.coop/%s#%s',
share: 'https://join.anytype.io/',
notionFAQ: 'https://doc.anytype.io/anytype-docs/basics/space/import-export#notion-import-faq',
publishDomain: '%s.coop',
publish: 'https://any.coop/%s/',
publishDomain: '%s.org',
publish: 'any.coop/%s',
api: '127.0.0.1:31009',
survey: {
register: 'https://community.anytype.io/survey0',
@ -34,4 +35,4 @@ export default {
shared: 'https://community.anytype.io/survey4',
multiplayer: 'https://community.anytype.io/survey5'
}
};
};

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

@ -68,7 +68,6 @@
}
}
.block.blockMedia > .wrapContent { border-radius: 8px; box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.05); }
.block.blockMedia.isAudio > .wrapContent { border: 1px solid var(--color-shape-secondary); }
.block.blockMedia.isAudio > .wrapContent > .selectionTarget > .dropTarget > .focusable > .wrap { width: 100%; padding: 12px 12px 7px 14px; }

View file

@ -98,12 +98,14 @@
.icon { width: 20px; height: 20px; margin-top: -4px; }
.icon.help { background-image: url('~img/icon/help.svg'); }
.full, .c70, .half { margin: 16px 0px; border-radius: 8px; display: block; }
.c50, .c60, .c70, .half, .full, .screen { margin: 16px auto; border-radius: 8px; display: block; }
.full { width: 100%; }
.c70 { width: 70%; margin: 16px auto; }
.half { width: 50%; }
.screen { margin: 16px auto; display: block; box-shadow: 0px 0px 25px rgba(0,0,0,0.2); }
.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); }
img.mention { margin-left: -18px; }
}
@ -273,4 +275,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

@ -22,7 +22,7 @@
}
.icon.sortArrow { width: 20px; height: 20px; margin: 0px; background-image: url('~img/icon/sortArrow.svg'); }
.icon.sortArrow.c1 { transform: rotateZ(180deg); }
.icon.sortArrow.c0 { transform: rotateZ(180deg); }
}
.row { border-bottom: 1px solid var(--color-shape-secondary); }

View file

@ -13,13 +13,27 @@
.input.isReadonly { background: rgba(0, 0, 0, 0.03); }
.input.isFocused { box-shadow: 0px 0px 0px 1px var(--color-system-accent-50); border-color: var(--color-system-accent-50); }
.label.small { @include text-small; @include text-overflow-nw; color: var(--color-text-secondary); }
.label.small { @include text-small; color: var(--color-text-secondary); @include text-overflow-nw; }
.flex { padding: 3px 0px; align-items: center; gap: 0px 16px; justify-content: space-between; }
.flex {
.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

@ -111,7 +111,7 @@ const Controls = observer(class Controls extends React.Component<Props> {
{views.map((item: I.View, i: number) => (
<ViewItem key={i} {...item} index={i} disabled={readonly} />
))}
{allowedView ? <Icon id={`button-${block.id}-view-add`} className="plus" tooltip={translate('blockDataviewControlsViewAdd')} onClick={this.onViewAdd} /> : ''}
{allowedView ? <Icon id={`button-${block.id}-view-add`} className="plus withBackground" tooltip={translate('blockDataviewControlsViewAdd')} onClick={this.onViewAdd} /> : ''}
</div>
));
@ -387,12 +387,16 @@ const Controls = observer(class Controls extends React.Component<Props> {
const sources = getSources();
const object = getTarget();
const view = getView();
const type = S.Record.getTypeById(object.type);
const viewType = type?.defaultViewType || I.ViewType.Grid;
console.log(type);
const newView = {
...view,
id: '',
name: translate(`viewName${I.ViewType.Grid}`),
type: I.ViewType.Grid,
groupRelationKey: view.groupRelationKey || Relation.getGroupOption(rootId, block.id, view.type, '')?.id,
name: translate(`viewName${viewType}`),
type: viewType,
groupRelationKey: view.groupRelationKey || Relation.getGroupOption(rootId, block.id, viewType, '')?.id,
cardSize: view.cardSize || I.CardSize.Medium,
filters: [],
sorts: [],

View file

@ -1484,7 +1484,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

@ -1,4 +1,4 @@
import React, { forwardRef, useImperativeHandle, useEffect } from 'react';
import React, { forwardRef, useImperativeHandle, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { IconObject, Pager, ObjectName, Cell, SelectionTarget, Icon } from 'Component';
import { I, C, S, U, J, Relation, translate, keyboard, analytics } from 'Lib';
@ -45,8 +45,8 @@ const ListObject = observer(forwardRef<ListObjectRefProps, Props>(({
route = '',
}, ref) => {
const [ sortId, setSortId ] = React.useState('');
const [ sortType, setSortType ] = React.useState(I.SortType.Asc);
const [ sortId, setSortId ] = useState('');
const [ sortType, setSortType ] = useState(I.SortType.Asc);
const { offset, total } = S.Record.getMeta(subId, '');
const { dateFormat } = S.Common;

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, IconObject, Switch } from 'Component';
import { I, C, S, J, keyboard, Dataview, translate } from 'Lib';
import { I, C, S, J, 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);
@ -131,19 +131,19 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
element: $(e.currentTarget),
typeY: I.MenuDirection.Bottom,
typeX: I.MenuDirection.Left,
delay: 0,
});
analytics.event('ShowShareObjectHelp', { objectType: object.type });
};
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 },
@ -158,6 +158,10 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
if (isOnline) {
loadStatus();
};
return () => {
Preview.tooltipHide(true);
};
}, []);
useEffect(() => {
@ -170,7 +174,7 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
<>
<div className="menuHeader">
<Title text={translate('menuPublishTitle')} />
<Icon className="info" onMouseEnter={showInfo} onMouseLeave={() => Preview.tooltipHide()} />
<Icon className="info" onClick={showInfo} />
</div>
<Input value={domain} readonly={true} />
@ -179,14 +183,23 @@ const MenuPublish = observer(forwardRef<I.MenuRef, I.Menu>((props, ref) => {
value={slug}
focusOnMount={true}
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">
<Label text={translate('menuPublishLabelJoin')} />
<div className="value">
<Switch ref={joinRef} onChange={(e, v) => onJoinSwitch(v)} />
<Switch ref={joinRef} value={true} onChange={(e, v) => onJoinSwitch(v)} />
</div>
</div>
) : ''}

View file

@ -456,7 +456,7 @@ const MenuSearchObject = observer(class MenuSearchObject extends React.Component
addParam.onClick(details);
close();
} else {
const flags = [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate ];
const flags = [ I.ObjectFlag.SelectTemplate ];
U.Object.create('', '', details, I.BlockPosition.Bottom, '', flags, route || analytics.route.search, (message: any) => {
process(message.details, true);

View file

@ -104,13 +104,12 @@ const HeadSimple = observer(class Controls extends React.Component<Props> {
if (isTypeOrRelation) {
if (object.isInstalled) {
if (isType && !allowDetails) {
if (isType && allowDetails) {
buttonEdit = <Button id="button-edit" color="blank" className="c28" text={translate('commonEdit')} onClick={onEdit} />;
};
} else {
const cn = [ 'c36' ];
const isInstalled = this.isInstalled();
const onClick = isInstalled ? null : this.onInstall;
const color = isInstalled ? 'blank' : 'black';

View file

@ -144,7 +144,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;
@ -154,13 +154,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

@ -37,7 +37,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,8 +79,12 @@ 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: 'update', name: translate('menuPublishButtonUpdate') },
{ id: 'open', name: translate('menuPublishButtonOpen') },
{ isDiv: true },
{ id: 'view', name: translate('menuPublishButtonView') },
{ id: 'copy', name: translate('menuPublishButtonCopy') },
{ id: 'unpublish', name: translate('menuPublishButtonUnpublish'), color: 'red' },
];
@ -104,8 +99,18 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
options,
onSelect: (e: any, element: any) => {
switch (element.id) {
case 'update': {
this.onUpdate(item);
case 'open': {
U.Object.openAuto(object);
break;
};
case 'view': {
this.onClick(item);
break;
};
case 'copy': {
U.Common.copyToast(translate('commonLink'), U.Space.getPublishUrl(item.uri));
break;
};
@ -119,25 +124,8 @@ const PopupSettingsPageDataPublish = observer(class PopupSettingsPageDataPublish
});
};
onUpdate (item: any) {
const object = S.Detail.get(SUB_ID, item.objectId);
C.PublishingCreate(S.Common.space, item.objectId, item.uri, false, (message: any) => {
if (message.error.code) {
return;
};
if (message.url) {
Action.openUrl(message.url);
analytics.event('ShareObjectPublish', { objectType: object.type });
};
});
analytics.event('ClickShareObjectPublish', { objectType: object.type });
};
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) {
@ -770,6 +776,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);
};
@ -829,7 +839,7 @@ const PopupSearch = observer(class PopupSearch extends React.Component<I.Popup,
} else {
switch (item.id) {
case 'add': {
keyboard.pageCreate({ name: filter }, 'Search');
this.pageCreate(filter)
break;
};

View file

@ -132,7 +132,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 () {
@ -184,7 +184,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));
};
};
@ -230,10 +230,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

@ -230,4 +230,4 @@ const SidebarLeft = observer(class SidebarLeft extends React.Component<{}, State
});
export default SidebarLeft;
export default SidebarLeft;

View file

@ -115,7 +115,7 @@ const SidebarPageObject = observer(class SidebarPageObject extends React.Compone
>
<div className="inner">
<div className="head">
<div className="titleWrap" onClick={() => sidebar.objectContainerToggle()}>
<div className="titleWrap" onClick={() => sidebar.objectContainerSwitch('widget')}>
<div className="side left">
<Icon className="back withBackground" />
<Title text={translate('commonAllContent')} />
@ -570,7 +570,7 @@ const SidebarPageObject = observer(class SidebarPageObject extends React.Compone
if (this.type == I.ObjectContainerType.Type) {
sidebar.rightPanelToggle(true, true, isPopup, 'type', { details });
}else {
keyboard.pageCreate(details, analytics.route.allObjects, (message: any) => {
keyboard.pageCreate(details, analytics.route.allObjects, [ I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ], (message: any) => {
cb(message.targetId);
});
};
@ -747,7 +747,7 @@ const SidebarPageObject = observer(class SidebarPageObject extends React.Compone
if (this.selected) {
this.clearSelection();
} else {
sidebar.objectContainerToggle();
sidebar.objectContainerSwitch('widget');
};
});

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,119 @@
import * as React from 'react';
import $ from 'jquery';
import { observer } from 'mobx-react';
import { IconObject, ObjectName, ObjectDescription, ObjectType, Icon } from 'Component';
import { I, U, S } from 'Lib';
interface Props {
item: any;
style?: any;
compact?: boolean;
isLocked?: boolean;
onClick?: (item: any) => void;
onContext?: (item: any) => void;
onMouseEnter?: (item: any) => void;
onMouseLeave?: (item: any) => void;
};
const ObjectItem = observer(class ObjectItem extends React.Component<Props> {
node = null;
render() {
const { item, style, compact, onClick, onContext, onMouseEnter, onMouseLeave } = this.props;
const cn = [ 'item', U.Data.layoutClass(item.id, item.layout) ];
const type = S.Record.getTypeById(item.type);
const isFile = U.Object.isInFileLayouts(item.layout);
const isTypeOrRelation = U.Object.isTypeOrRelationLayout(item.layout);
const canEdit = U.Object.isTaskLayout(item.layout) && S.Block.isAllowed(item.restrictions, [ I.RestrictionObject.Details ]);
if (compact) {
cn.push('isCompact');
};
let iconSmall = null;
let iconLarge = null;
let description = null;
let content = null;
if (compact) {
iconSmall = <IconObject object={item} size={18} iconSize={18} canEdit={canEdit} />;
} else {
const iconSize = isFile ? 48 : null;
iconLarge = <IconObject object={item} size={48} iconSize={iconSize} canEdit={canEdit} />;
description = <ObjectDescription object={item} />;
};
if (isFile) {
cn.push('isFile');
description = <div className="descr">{U.File.size(item.sizeInBytes)}</div>;
};
if (isTypeOrRelation) {
description = null;
};
if (!compact) {
content = (
<>
{iconLarge}
<div className="info">
<div className="nameWrap">
<ObjectName object={item} />
</div>
<div className="bottomWrap">
<div className="type">
<ObjectType object={type} />
</div>
<div className="bullet" />
{description}
</div>
</div>
</>
);
} else {
content = (
<>
<div className="nameWrap">
{iconSmall}
<ObjectName object={item} />
</div>
</>
);
};
return (
<div
ref={ref => this.node = ref}
id={`item-${item.id}`}
className={cn.join(' ')}
style={style}
onClick={onClick}
onContextMenu={onContext}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
{content}
</div>
);
};
componentDidMount () {
this.resize();
};
componentDidUpdate () {
this.resize();
};
resize () {
const node = $(this.node);
node.toggleClass('withIcon', !!node.find('.iconObject').length);
node.toggleClass('withDescr', !!node.find('.descr').length);
};
});
export default ObjectItem;

View file

@ -64,6 +64,7 @@ const SidebarPageType = observer(class SidebarPageType extends React.Component<I
componentDidMount (): void {
this.init();
this.loadConflicts();
window.setTimeout(() => this.previewRef?.show(true), J.Constant.delay.sidebar);
};
@ -87,7 +88,7 @@ const SidebarPageType = observer(class SidebarPageType extends React.Component<I
layoutWidth: 0,
layoutFormat: I.LayoutFormat.Page,
recommendedFeaturedRelations: [],
defaultView: I.ViewType.Grid,
defaultViewType: I.ViewType.Grid,
}, details);
this.object = U.Common.objectCopy(details.isNew ? newType : type || newType);
@ -123,7 +124,13 @@ const SidebarPageType = observer(class SidebarPageType extends React.Component<I
};
onChange (section: string, update: any) {
const skipFormat = [ 'defaultTypeId' ];
for (const relationKey in update) {
if (skipFormat.includes(relationKey)) {
continue;
};
const relation = S.Record.getRelationByKey(relationKey);
update[relationKey] = Relation.formatValue(relation, update[relationKey], false);
@ -179,18 +186,23 @@ const SidebarPageType = observer(class SidebarPageType extends React.Component<I
loadConflicts () {
const { space } = S.Common;
const { rootId } = this.props;
const type = this.getObject();
C.ObjectTypeListConflictingRelations(rootId, space, (message) => {
if (!message.error.code) {
this.conflicts = Relation
.getArrayValue(message.conflictRelationIds)
.map(id => S.Record.getRelationById(id))
.filter(it => it && !Relation.isSystem(it.relationKey))
.map(it => it.id);
if (!type) {
return;
};
this.forceUpdate();
C.ObjectTypeListConflictingRelations(type.id, space, (message) => {
if (message.error.code) {
return;
};
this.conflicts = Relation.getArrayValue(message.conflictRelationIds)
.map(id => S.Record.getRelationById(id))
.filter(it => it && !Relation.isSystem(it.relationKey))
.map(it => it.id);
this.forceUpdate();
});
};

View file

@ -15,7 +15,7 @@ const SidebarLayoutPreview = observer(class SidebarLayoutPreview extends React.C
layoutAlign: I.BlockHAlign.Left,
layoutWidth: 0,
layoutFormat: I.LayoutFormat.Page,
defaultView: I.ViewType.Grid,
defaultViewType: I.ViewType.Grid,
};
constructor (props: I.SidebarPageComponent) {
@ -181,7 +181,7 @@ const SidebarLayoutPreview = observer(class SidebarLayoutPreview extends React.C
};
getViewType () {
return Number(this.object.defaultView) || I.ViewType.Grid;
return Number(this.object.defaultViewType) || I.ViewType.Grid;
};
getNodeWidth (): number {

View file

@ -19,10 +19,8 @@ const SidebarSectionTypeLayoutFormatList = observer(class SidebarSectionTypeLayo
render () {
const { object, onChange, readonly } = this.props;
const defaultViewOptions = U.Menu.prepareForSelect(U.Menu.getViews().filter(it => it.id != I.ViewType.Graph));
const typeId = object.defaultType;
const type = S.Record.getTypeById(typeId);
const defaultViewOptions = U.Menu.getViews().filter(it => it.id != I.ViewType.Graph);
const type = S.Record.getTypeById(object.defaultTypeId);
return (
<div className="items">
@ -36,9 +34,9 @@ const SidebarSectionTypeLayoutFormatList = observer(class SidebarSectionTypeLayo
ref={ref => this.refDefaultView = ref}
id={`sidebar-layout-default-view-${object.id}`}
options={defaultViewOptions}
value={object.defaultView}
value={object.defaultViewType}
arrowClassName="light"
onChange={id => onChange({ defaultView: id })}
onChange={id => onChange({ defaultViewType: id })}
readonly={readonly}
menuParam={{
className: 'fixed',
@ -98,17 +96,14 @@ const SidebarSectionTypeLayoutFormatList = observer(class SidebarSectionTypeLayo
{ relationKey: 'uniqueKey', condition: I.FilterCondition.NotEqual, value: J.Constant.typeKey.template },
],
onClick: (item: any) => {
onChange({ defaultType: item.id })
onChange({ defaultTypeId: item.id });
},
}
});
};
setValue () {
const { object } = this.props;
this.refDefaultView.setValue(object.defaultView);
this.refDefaultView.setValue(String(this.props.object.defaultViewType));
};
});

View file

@ -177,7 +177,7 @@ const WidgetIndex = observer(forwardRef<{}, Props>((props, ref) => {
};
details.layout = type.recommendedLayout;
flags = flags.concat([ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate ]);
flags = flags.concat([ I.ObjectFlag.SelectTemplate ]);
typeKey = type.uniqueKey;
templateId = type.defaultTemplateId;
break;

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,
@ -31,11 +34,6 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
openSettings('spaceIndex');
};
const onRequest = (e: MouseEvent) => {
e.stopPropagation();
openSettings('spaceShare');
};
const onImport = (e: MouseEvent) => {
e.stopPropagation();
openSettings('importIndex');
@ -48,7 +46,7 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
const onCreate = (e: MouseEvent) => {
e.stopPropagation();
keyboard.pageCreate({}, analytics.route.navigation);
keyboard.pageCreate({}, analytics.route.navigation, [ I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
};
const onMore = (e: MouseEvent, context: any, item: any) => {
@ -237,7 +235,7 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
};
case 'all': {
sidebar.objectContainerToggle();
sidebar.objectContainerSwitch('object');
break;
};
@ -248,6 +246,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 +272,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>
@ -306,4 +315,4 @@ const WidgetSpace = observer(forwardRef<{}, I.WidgetComponent>((props, ref) => {
}));
export default WidgetSpace;
export default WidgetSpace;

View file

@ -13,11 +13,12 @@ const HEIGHT_LIST = 64;
const WidgetViewList = observer(forwardRef<{}, I.WidgetViewComponent>((props, ref) => {
const { parent, block, isPreview, subId, getRecordIds, addGroupLabels } = props;
const { parent, block, isPreview, subId, getRecordIds, addGroupLabels, getView } = props;
const cache = useRef({});
const nodeRef = useRef(null);
const listRef = useRef(null);
const top = useRef(0);
const view = getView();
const { total } = S.Record.getMeta(subId, '');
const isCompact = [ I.WidgetLayout.Compact, I.WidgetLayout.View ].includes(parent.content.layout);
@ -157,6 +158,7 @@ const WidgetViewList = observer(forwardRef<{}, I.WidgetViewComponent>((props, re
style={style}
index={index}
isCompact={isCompact}
hideIcon={view?.hideIcon}
/>
</CellMeasurer>
);
@ -217,6 +219,7 @@ const WidgetViewList = observer(forwardRef<{}, I.WidgetViewComponent>((props, re
subId={subId}
id={item.id}
isCompact={isCompact}
hideIcon={view?.hideIcon}
/>
))}
</>

View file

@ -14,11 +14,12 @@ interface Props extends I.WidgetViewComponent {
isCompact?: boolean;
isPreview?: boolean;
isSection?: boolean;
hideIcon?: boolean;
};
const WidgetListItem = observer(forwardRef<{}, Props>((props, ref) => {
const { subId, id, block, style, isCompact, isEditing, index, isPreview, isSection, onContext } = props;
const { subId, id, block, style, isCompact, isEditing, index, isPreview, isSection, hideIcon, onContext } = props;
const rootId = keyboard.getRootId();
const object = S.Detail.get(subId, id, J.Relation.sidebar);
const { isReadonly, isArchived, isHidden, restrictions, source } = object;
@ -88,6 +89,24 @@ const WidgetListItem = observer(forwardRef<{}, Props>((props, ref) => {
let descr = null;
let more = null;
let icon = null;
if (!hideIcon) {
icon = (
<IconObject
id={iconKey}
key={iconKey}
object={object}
size={isCompact ? 18 : 48}
iconSize={isCompact ? 18 : 28}
canEdit={!isReadonly && !isArchived && allowedDetails && U.Object.isTaskLayout(object.layout)}
menuParam={{
className: 'fixed',
classNameWrap: 'fromSidebar',
}}
/>
);
};
if (!isCompact) {
if (U.Object.isBookmarkLayout(object.layout)) {
@ -103,18 +122,7 @@ const WidgetListItem = observer(forwardRef<{}, Props>((props, ref) => {
let inner = (
<div className="inner" onMouseDown={onClick}>
<IconObject
id={iconKey}
key={iconKey}
object={object}
size={isCompact ? 18 : 48}
iconSize={isCompact ? 18 : 28}
canEdit={!isReadonly && !isArchived && allowedDetails && U.Object.isTaskLayout(object.layout)}
menuParam={{
className: 'fixed',
classNameWrap: 'fromSidebar',
}}
/>
{icon}
<div className="info">
<ObjectName object={object} />

View file

@ -22,51 +22,71 @@ 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`, `c70`),
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.`),
img(`45/6.png`, `c70`),
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`, `c70`),
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`),
bullet(`Making changes to Kanban in the Version History is now disabled. Thanks, @${link('https://community.anytype.io/t/making-changes-to-kanban-in-version-history-breaks-all-versions/26141', 'HeavensRegent')}!`),
@ -74,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

@ -72,9 +72,10 @@ export enum ObjectOrigin {
Usecase = 6,
Builtin = 7,
Bookmark = 8,
Api = 9,
};
export enum LayoutFormat {
Page = 0,
List = 1,
};
};

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

@ -174,6 +174,7 @@ export const AccountCreate = (name: string, avatarPath: string, storePath: strin
request.setIcon(icon);
request.setNetworkmode(mode as number);
request.setNetworkcustomconfigfilepath(networkConfigPath);
request.setJsonapilistenaddr(J.Url.api);
dispatcher.request(AccountCreate.name, request, callBack);
};
@ -191,6 +192,7 @@ export const AccountSelect = (id: string, path: string, mode: I.NetworkMode, net
request.setRootpath(path);
request.setNetworkmode(mode as number);
request.setNetworkcustomconfigfilepath(networkConfigPath);
request.setJsonapilistenaddr(J.Url.api);
dispatcher.request(AccountSelect.name, request, callBack);
};
@ -1949,7 +1951,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

@ -682,7 +682,7 @@ export const Mapper = {
return reactions;
},
PublishState: (obj: Rpc.Publishing.PublishState): I.PublishState => {
PublishState: (obj: Rpc.Publishing.PublishState): any => {
return {
spaceId: obj.getSpaceid(),
objectId: obj.getObjectid(),
@ -691,6 +691,7 @@ export const Mapper = {
version: obj.getVersion(),
timestamp: obj.getTimestamp(),
size: obj.getSize(),
//details: Decode.struct(obj.getDetails()),
};
},
@ -1097,7 +1098,7 @@ export const Mapper = {
if (v == V.ACCOUNTUPDATE) t = 'AccountUpdate';
if (v == V.ACCOUNTCONFIGUPDATE) t = 'AccountConfigUpdate';
if (v == V.ACCOUNTLINKCHALLENGE) t = 'AccountLinkChallenge';
//if (v == V.ACCOUNTLINKCHALLENGEHIDE) t = 'AccountLinkChallengeHide';
if (v == V.ACCOUNTLINKCHALLENGEHIDE) t = 'AccountLinkChallengeHide';
if (v == V.BLOCKADD) t = 'BlockAdd';
if (v == V.BLOCKDELETE) t = 'BlockDelete';
@ -1209,13 +1210,11 @@ export const Mapper = {
};
},
/*
AccountLinkChallengeHide: (obj: Events.Event.Account.LinkChallengeHide) => {
return {
challenge: obj.getChallenge(),
};
},
*/
ObjectRelationsAmend: (obj: Events.Event.Object.Relations.Amend) => {
return {

View file

@ -66,6 +66,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);
});
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, () => {
@ -294,13 +301,11 @@ class Keyboard {
return false;
};
pageCreate (details: any, route: string, callBack?: (message: any) => void) {
pageCreate (details: any, route: string, flags: I.ObjectFlag[], callBack?: (message: any) => void) {
if (!this.isMain()) {
return;
};
const flags = [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ];
U.Object.create('', '', details, I.BlockPosition.Bottom, '', flags, route, message => {
U.Object.openConfig(message.details);
@ -495,7 +500,7 @@ class Keyboard {
};
case 'createObject': {
this.pageCreate({}, route);
this.pageCreate({}, route, [ I.ObjectFlag.SelectType, I.ObjectFlag.SelectTemplate, I.ObjectFlag.DeleteEmpty ]);
break;
};
@ -527,7 +532,7 @@ class Keyboard {
return;
};
Renderer.send('openPath', paths[0]);
Action.openPath(paths[0]);
});
});
break;
@ -537,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]);
};
});
});
@ -548,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;
@ -558,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;
@ -567,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;
@ -576,7 +581,7 @@ class Keyboard {
case 'debugProcess': {
C.DebugStackGoroutines(logPath, (message: any) => {
if (!message.error.code) {
Renderer.send('openPath', logPath);
Action.openPath(logPath);
};
});
break;
@ -627,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

@ -45,9 +45,13 @@ class Preview {
const { element } = param;
const typeX = Number(param.typeX) || I.MenuDirection.Center;
const typeY = Number(param.typeY) || I.MenuDirection.Top;
const delay = Number(param.delay) || DELAY_TOOLTIP;
const offsetX = Number(param.offsetX) || 0;
const offsetY = Number(param.offsetY) || 0;
let delay = DELAY_TOOLTIP;
if (undefined !== param.delay) {
delay = param.delay;
};
if (!element.length || keyboard.isResizing) {
return;
@ -56,7 +60,7 @@ class Preview {
let text = String(param.text || '').replace(/\\n/g, '\n');
text = U.Common.lbBr(U.Common.sanitize(text));
this.delayTooltip = delay;
this.delayTooltip = Number(delay) || 0;
window.clearTimeout(this.timeout.tooltip);
this.timeout.tooltip = window.setTimeout(() => {
@ -128,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

@ -360,14 +360,13 @@ class Sidebar {
return J.Size.vault.width / width * J.Constant.delay.sidebar;
};
objectContainerToggle () {
objectContainerSwitch (page: string) {
const ref = S.Common.getRef('sidebarLeft');
if (!ref) {
return;
};
const page = ref.state.page;
ref.setState({ page: (page == 'object' ? '' : 'object') });
ref.setState({ page });
};
rightPanelToggle (v: boolean, animate: boolean, isPopup: boolean, page?: string, param?: any) {

View file

@ -25,7 +25,7 @@ const Api = {
if (electron.storeGet) {
return electron.storeGet(key);
} else {
return localStorage.getItem(key);
return Api.parse(localStorage.getItem(key));
};
},
@ -44,6 +44,16 @@ const Api = {
localStorage.removeItem(key);
};
},
parse: (s: string) => {
if (!s) {
return;
};
let ret = '';
try { ret = JSON.parse(s); } catch (e) { /**/ };
return ret;
},
};
class Storage {
@ -56,7 +66,7 @@ class Storage {
let o = Api.get(key);
if (undefined === o) {
o = this.parse(String(localStorage.getItem(key) || ''));
o = Api.parse(String(localStorage.getItem(key) || ''));
};
if (this.isSpaceKey(key)) {
@ -105,8 +115,7 @@ class Storage {
if (this.isAccountKey(key)) {
this.deleteAccountKey(key);
} else {
U.Common.getElectron().storeDelete(key);
localStorage.removeItem(key);
Api.delete(key);
};
};
@ -461,16 +470,6 @@ class Storage {
keys.forEach(key => this.delete(key));
};
parse (s: string) {
if (!s) {
return;
};
let ret = '';
try { ret = JSON.parse(s); } catch (e) { /**/ };
return ret;
};
setChat (id: string, obj: any) {
if (!id) {
return;

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);
};
});

View file

@ -275,8 +275,8 @@ class UtilSpace {
const participant = this.getMyParticipant();
let domain = '';
if (participant.resolvedName) {
domain = U.Common.sprintf(J.Url.publishDomain, participant.resolvedName);
if (participant.globalName) {
domain = U.Common.sprintf(J.Url.publishDomain, participant.globalName);
} else {
domain = U.Common.sprintf(J.Url.publish, participant.identity);
};