mirror of https://github.com/vector-im/riot-web
Iterate PR; tidy and improve widget context menu
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/21833/head
parent
f5479d87fe
commit
f198b95579
|
@ -141,12 +141,6 @@ limitations under the License.
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
min-width: 24px; // prevent flexbox crushing
|
min-width: 24px; // prevent flexbox crushing
|
||||||
|
|
||||||
.mx_AccessibleTooltipButton_container {
|
|
||||||
// TODO
|
|
||||||
position: absolute;
|
|
||||||
top: -50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
|
@ -98,12 +98,16 @@ $MiniAppTileHeight: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this should be 300px but that's too large
|
||||||
|
$MinWidth: 240px;
|
||||||
|
|
||||||
.mx_AppsDrawer_has2 .mx_AppTile {
|
.mx_AppsDrawer_has2 .mx_AppTile {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
|
|
||||||
&:nth-child(3) {
|
&:nth-child(3) {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
width: 0;
|
width: 0 !important;
|
||||||
|
min-width: $MinWidth !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mx_AppsDrawer_has3 .mx_AppTile {
|
.mx_AppsDrawer_has3 .mx_AppTile {
|
||||||
|
@ -111,13 +115,14 @@ $MiniAppTileHeight: 200px;
|
||||||
|
|
||||||
&:nth-child(3) {
|
&:nth-child(3) {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
width: 0;
|
width: 0 !important;
|
||||||
|
min-width: $MinWidth !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_AppTile {
|
.mx_AppTile {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
min-width: 200px;
|
min-width: $MinWidth;
|
||||||
border: 8px solid $widget-menu-bar-bg-color;
|
border: 8px solid $widget-menu-bar-bg-color;
|
||||||
border-left-width: 5px;
|
border-left-width: 5px;
|
||||||
border-right-width: 5px;
|
border-right-width: 5px;
|
||||||
|
|
|
@ -1374,7 +1374,7 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
private onAppsClick = () => {
|
private onAppsClick = () => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: "appsDrawer", // TODO should this go into the RVS?
|
action: "appsDrawer",
|
||||||
show: !this.state.showApps,
|
show: !this.state.showApps,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,6 +56,7 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
||||||
if (showUnpin) {
|
if (showUnpin) {
|
||||||
const onUnpinClick = () => {
|
const onUnpinClick = () => {
|
||||||
WidgetStore.instance.unpinWidget(app.id);
|
WidgetStore.instance.unpinWidget(app.id);
|
||||||
|
onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
unpinButton = <IconizedContextMenuOption onClick={onUnpinClick} label={_t("Unpin")} />;
|
unpinButton = <IconizedContextMenuOption onClick={onUnpinClick} label={_t("Unpin")} />;
|
||||||
|
@ -65,9 +66,10 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
||||||
if (canModify && WidgetUtils.isManagedByManager(app)) {
|
if (canModify && WidgetUtils.isManagedByManager(app)) {
|
||||||
const onEditClick = () => {
|
const onEditClick = () => {
|
||||||
WidgetUtils.editWidget(room, app);
|
WidgetUtils.editWidget(room, app);
|
||||||
|
onFinished();
|
||||||
};
|
};
|
||||||
|
|
||||||
editButton = <IconizedContextMenuOption onClick={onEditClick} label={_t("Edit")} />
|
editButton = <IconizedContextMenuOption onClick={onEditClick} label={_t("Edit")} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let snapshotButton;
|
let snapshotButton;
|
||||||
|
@ -128,13 +130,38 @@ const WidgetContextMenu: React.FC<IProps> = ({
|
||||||
revokeButton = <IconizedContextMenuOption onClick={onRevokeClick} label={_t("Remove for me")} />;
|
revokeButton = <IconizedContextMenuOption onClick={onRevokeClick} label={_t("Remove for me")} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pinnedWidgets = WidgetStore.instance.getPinnedApps(roomId);
|
||||||
|
const widgetIndex = pinnedWidgets.findIndex(widget => widget.id === app.id);
|
||||||
|
|
||||||
|
let moveLeftButton;
|
||||||
|
if (showUnpin && widgetIndex > 0) {
|
||||||
|
const onClick = () => {
|
||||||
|
WidgetStore.instance.movePinnedWidget(app.id, -1);
|
||||||
|
onFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
moveLeftButton = <IconizedContextMenuOption onClick={onClick} label={_t("Move left")} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moveRightButton;
|
||||||
|
if (showUnpin && widgetIndex < pinnedWidgets.length - 1) {
|
||||||
|
const onClick = () => {
|
||||||
|
WidgetStore.instance.movePinnedWidget(app.id, 1);
|
||||||
|
onFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
moveRightButton = <IconizedContextMenuOption onClick={onClick} label={_t("Move right")} />;
|
||||||
|
}
|
||||||
|
|
||||||
return <IconizedContextMenu {...props} chevronFace={ChevronFace.None} onFinished={onFinished}>
|
return <IconizedContextMenu {...props} chevronFace={ChevronFace.None} onFinished={onFinished}>
|
||||||
<IconizedContextMenuOptionList>
|
<IconizedContextMenuOptionList>
|
||||||
{ unpinButton }
|
|
||||||
{ snapshotButton }
|
|
||||||
{ editButton }
|
{ editButton }
|
||||||
{ deleteButton }
|
|
||||||
{ revokeButton }
|
{ revokeButton }
|
||||||
|
{ deleteButton }
|
||||||
|
{ snapshotButton }
|
||||||
|
{ moveLeftButton }
|
||||||
|
{ moveRightButton }
|
||||||
|
{ unpinButton }
|
||||||
</IconizedContextMenuOptionList>
|
</IconizedContextMenuOptionList>
|
||||||
</IconizedContextMenu>;
|
</IconizedContextMenu>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -95,7 +95,7 @@ export default class AppsDrawer extends React.Component {
|
||||||
// persist to localStorage
|
// persist to localStorage
|
||||||
console.log("@@ _saveResizerPreferences");
|
console.log("@@ _saveResizerPreferences");
|
||||||
localStorage.setItem(this._getStorageKey(), JSON.stringify([
|
localStorage.setItem(this._getStorageKey(), JSON.stringify([
|
||||||
this._getAppsHash(this.state.apps),
|
this.state.apps.map(app => app.id),
|
||||||
...this.state.apps.slice(1).map((_, i) => this.resizer.forHandleAt(i).size),
|
...this.state.apps.slice(1).map((_, i) => this.resizer.forHandleAt(i).size),
|
||||||
]));
|
]));
|
||||||
},
|
},
|
||||||
|
@ -133,10 +133,9 @@ export default class AppsDrawer extends React.Component {
|
||||||
_loadResizerPreferences = () => {
|
_loadResizerPreferences = () => {
|
||||||
console.log("@@ _loadResizerPreferences");
|
console.log("@@ _loadResizerPreferences");
|
||||||
try {
|
try {
|
||||||
const [idString, ...sizes] = JSON.parse(localStorage.getItem(this._getStorageKey()));
|
const [[...lastIds], ...sizes] = JSON.parse(localStorage.getItem(this._getStorageKey()));
|
||||||
// format: [idString: string, ...percentages: string];
|
// Every app was included in the last split, reuse the last sizes
|
||||||
// TODO determine the exact behaviour we want for layout changing when pinning/unpinning
|
if (this.state.apps.length <= lastIds.length && this.state.apps.every(app => lastIds.includes(app.id))) {
|
||||||
if (this._getAppsHash() === idString || true) {
|
|
||||||
sizes.forEach((size, i) => {
|
sizes.forEach((size, i) => {
|
||||||
const distributor = this.resizer.forHandleAt(i);
|
const distributor = this.resizer.forHandleAt(i);
|
||||||
if (distributor) {
|
if (distributor) {
|
||||||
|
|
|
@ -92,10 +92,8 @@ export default class Sizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
public start(item: HTMLElement) {}
|
public start(item: HTMLElement) {}
|
||||||
|
|
||||||
// TODO
|
|
||||||
public finish(item: HTMLElement) {}
|
public finish(item: HTMLElement) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -205,7 +205,38 @@ export default class WidgetStore extends AsyncStoreWithClient<IState> {
|
||||||
this.emit(UPDATE_EVENT);
|
this.emit(UPDATE_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPinnedApps(roomId): IApp[] {
|
public movePinnedWidget(widgetId: string, delta: 1 | -1) {
|
||||||
|
// TODO simplify this by changing the storage medium of pinned to an array once the Jitsi default-on goes away
|
||||||
|
const roomId = this.getRoomId(widgetId);
|
||||||
|
const roomInfo = this.getRoom(roomId);
|
||||||
|
if (!roomInfo || roomInfo.pinned[widgetId] === false) return;
|
||||||
|
|
||||||
|
const pinnedApps = this.getPinnedApps(roomId).map(app => app.id);
|
||||||
|
const i = pinnedApps.findIndex(id => id === widgetId);
|
||||||
|
|
||||||
|
if (delta > 0) {
|
||||||
|
pinnedApps.splice(i, 2, pinnedApps[i + 1], pinnedApps[i]);
|
||||||
|
} else {
|
||||||
|
pinnedApps.splice(i - 1, 2, pinnedApps[i], pinnedApps[i - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const reorderedPinned: IRoomWidgets["pinned"] = {};
|
||||||
|
pinnedApps.forEach(id => {
|
||||||
|
reorderedPinned[id] = true;
|
||||||
|
});
|
||||||
|
Object.keys(roomInfo.pinned).forEach(id => {
|
||||||
|
if (reorderedPinned[id] === undefined) {
|
||||||
|
reorderedPinned[id] = roomInfo.pinned[id];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
roomInfo.pinned = reorderedPinned;
|
||||||
|
|
||||||
|
SettingsStore.setValue("Widgets.pinned", roomId, SettingLevel.ROOM_ACCOUNT, roomInfo.pinned);
|
||||||
|
this.emit(roomId);
|
||||||
|
this.emit(UPDATE_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPinnedApps(roomId: string): IApp[] {
|
||||||
// returns the apps in the order they were pinned with, up to the maximum
|
// returns the apps in the order they were pinned with, up to the maximum
|
||||||
const roomInfo = this.getRoom(roomId);
|
const roomInfo = this.getRoom(roomId);
|
||||||
if (!roomInfo) return [];
|
if (!roomInfo) return [];
|
||||||
|
|
Loading…
Reference in New Issue