From 5c31c93636d339315b38f5159d77f9c20b492259 Mon Sep 17 00:00:00 2001 From: Akos Kitta Date: Thu, 16 Mar 2023 16:11:37 +0100 Subject: [PATCH] fix: relaxed hover service request when scrolling - do not render footer when scrolling - fix anchor word wrapping for long long links in the markdown - underline the link and change the cursor to pointer on hover - consider status-bar height when calculating hover top Signed-off-by: Akos Kitta --- .../src/browser/style/hover-service.css | 7 +++-- .../src/browser/style/list-widget.css | 4 +++ .../src/browser/theia/core/hover-service.ts | 2 +- .../component-list/component-list-item.tsx | 2 ++ .../widgets/component-list/component-list.tsx | 24 ++++++++++++++++- .../filterable-list-container.tsx | 3 +++ .../component-list/list-item-renderer.tsx | 26 ++++++++++++------- .../widgets/component-list/list-widget.tsx | 4 +++ 8 files changed, 59 insertions(+), 13 deletions(-) diff --git a/arduino-ide-extension/src/browser/style/hover-service.css b/arduino-ide-extension/src/browser/style/hover-service.css index 0468d4241..cf4218cf0 100644 --- a/arduino-ide-extension/src/browser/style/hover-service.css +++ b/arduino-ide-extension/src/browser/style/hover-service.css @@ -4,7 +4,7 @@ /* Adapted from https://github.com/microsoft/vscode/blob/7d9b1c37f8e5ae3772782ba3b09d827eb3fdd833/src/vs/workbench/services/hover/browser/hoverService.ts */ :root { - --theia-hover-max-width: 200px; + --theia-hover-max-width: 200px; /* customized */ } .theia-hover { @@ -29,10 +29,13 @@ .theia-hover a { color: var(--theia-textLink-foreground); + word-wrap: break-word; /* customized */ + cursor: pointer; /* customized */ } .theia-hover a:hover { - color: var(--theia-textLink-active-foreground); + /* color: var(--theia-textLink-active-foreground); */ + text-decoration: underline; /* customized */ } .theia-hover .hover-row .actions { diff --git a/arduino-ide-extension/src/browser/style/list-widget.css b/arduino-ide-extension/src/browser/style/list-widget.css index 0ce86919c..07d61a8d4 100644 --- a/arduino-ide-extension/src/browser/style/list-widget.css +++ b/arduino-ide-extension/src/browser/style/list-widget.css @@ -158,6 +158,10 @@ padding-top: 8px; } +.component-list-item .footer.scrolling { + visibility: hidden; +} + .component-list-item .footer > * { display: inline-block; } diff --git a/arduino-ide-extension/src/browser/theia/core/hover-service.ts b/arduino-ide-extension/src/browser/theia/core/hover-service.ts index 4dd2bee91..26bcd359f 100644 --- a/arduino-ide-extension/src/browser/theia/core/hover-service.ts +++ b/arduino-ide-extension/src/browser/theia/core/hover-service.ts @@ -144,7 +144,7 @@ export class HoverService { const documentWidth = document.body.getBoundingClientRect().width; // document.body.getBoundingClientRect().height doesn't work as expected // scrollHeight will always be accurate here: https://stackoverflow.com/a/44077777 - const documentHeight = document.documentElement.scrollHeight; + const documentHeight = document.documentElement.scrollHeight - 22; // --theia-statusBar-height: 22px; position = HoverPosition.invertIfNecessary( position, targetDimensions, diff --git a/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx b/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx index 83b0dea71..fcd93e128 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/component-list-item.tsx @@ -24,6 +24,7 @@ export class ComponentListItem< item, selectedVersion, inProgress: this.state.inProgress, + isScrolling: this.props.isScrolling, install: (item) => this.install(item), uninstall: (item) => this.uninstall(item), onVersionChange: (version) => this.onVersionChange(version), @@ -88,6 +89,7 @@ export namespace ComponentListItem { selectedVersion: Installable.Version ) => void; readonly itemRenderer: ListItemRenderer; + readonly isScrolling: boolean; } export interface State { diff --git a/arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx b/arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx index 86f4d3df7..20bc16212 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/component-list.tsx @@ -2,16 +2,33 @@ import * as React from '@theia/core/shared/react'; import { Virtuoso } from '@theia/core/shared/react-virtuoso'; import { ArduinoComponent } from '../../../common/protocol/arduino-component'; import { Installable } from '../../../common/protocol/installable'; +import { HoverService } from '../../theia/core/hover-service'; import { ComponentListItem } from './component-list-item'; import { ListItemRenderer } from './list-item-renderer'; export class ComponentList extends React.Component< - ComponentList.Props + ComponentList.Props, + ComponentList.State > { + constructor(props: Readonly>) { + super(props); + this.state = { + isScrolling: false, + }; + } + override render(): React.ReactNode { return ( { + if (this.state.isScrolling !== isScrolling) { + this.setState({ isScrolling }); + if (isScrolling) { + this.props.hoverService.cancelHover(); + } + } + }} itemContent={(_: number, item: T) => ( key={this.props.itemLabel(item)} @@ -21,6 +38,7 @@ export class ComponentList extends React.Component< uninstall={this.props.uninstall} edited={this.props.edited} onItemEdit={this.props.onItemEdit} + isScrolling={this.state.isScrolling} /> )} /> @@ -42,5 +60,9 @@ export namespace ComponentList { item: T, selectedVersion: Installable.Version ) => void; + readonly hoverService: HoverService; + } + export interface State { + isScrolling: boolean; } } diff --git a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx index d9f4f1531..0a73e5ec1 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/filterable-list-container.tsx @@ -15,6 +15,7 @@ import { ListItemRenderer } from './list-item-renderer'; import { ResponseServiceClient } from '../../../common/protocol'; import { nls } from '@theia/core/lib/common'; import { DisposableCollection } from '@theia/core/lib/common/disposable'; +import { HoverService } from '../../theia/core/hover-service'; export class FilterableListContainer< T extends ArduinoComponent, @@ -93,6 +94,7 @@ export class FilterableListContainer< uninstall={this.uninstall.bind(this)} edited={this.state.edited} onItemEdit={this.onItemEdit.bind(this)} + hoverService={this.props.hoverService} /> ); } @@ -193,6 +195,7 @@ export namespace FilterableListContainer { progressId: string; }) => Promise; readonly commandService: CommandService; + readonly hoverService: HoverService; } export interface State { diff --git a/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx b/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx index 6acf0f842..6a2f00ec3 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/list-item-renderer.tsx @@ -114,6 +114,7 @@ interface ListItemRendererParams { readonly item: T; readonly selectedVersion: Installable.Version | undefined; readonly inProgress?: 'installing' | 'uninstalling' | undefined; + readonly isScrolling: boolean; readonly install: (item: T) => Promise; readonly uninstall: (item: T) => Promise; readonly onVersionChange: (version: Installable.Version) => void; @@ -156,15 +157,17 @@ export class ListItemRenderer { private readonly showHover = ( event: React.MouseEvent, - markdown: string + params: ListItemRendererParams ) => { - this.hoverService.requestHover({ - content: new MarkdownStringImpl(markdown), - target: event.currentTarget, - position: 'right', - }); + if (!params.isScrolling) { + const markdown = this.markdown(params); + this.hoverService.requestHover({ + content: new MarkdownStringImpl(markdown), + target: event.currentTarget, + position: 'right', + }); + } }; - renderItem(params: ListItemRendererParams): React.ReactNode { const action = this.action(params); return ( @@ -172,7 +175,7 @@ export class ListItemRenderer {
this.showHover(event, this.markdown(params))} + onMouseOver={(event) => this.showHover(event, params)} >
extends React.Component< }> > { override render(): React.ReactNode { + const { isScrolling } = this.props.params; + const className = ['footer']; + if (isScrolling) { + className.push('scrolling'); + } return ( -
+
diff --git a/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx b/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx index e6dfd41b1..173ffcc48 100644 --- a/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx +++ b/arduino-ide-extension/src/browser/widgets/component-list/list-widget.tsx @@ -21,6 +21,7 @@ import { FilterableListContainer } from './filterable-list-container'; import { ListItemRenderer } from './list-item-renderer'; import { NotificationCenter } from '../../notification-center'; import { StatefulWidget } from '@theia/core/lib/browser'; +import { HoverService } from '../../theia/core/hover-service'; @injectable() export abstract class ListWidget< @@ -38,6 +39,8 @@ export abstract class ListWidget< private readonly commandService: CommandService; @inject(ResponseServiceClient) private readonly responseService: ResponseServiceClient; + @inject(HoverService) + private readonly hoverService: HoverService; /** * Do not touch or use it. It is for setting the focus on the `input` after the widget activation. @@ -162,6 +165,7 @@ export abstract class ListWidget< commandService={this.commandService} responseService={this.responseService} onDidShow={this.onDidShowEmitter.event} + hoverService={this.hoverService} /> ); }