From 220c24930511379dc862b144278a65ebb39a26a9 Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Thu, 23 May 2024 23:42:17 +0200 Subject: [PATCH 1/2] Add Tooltips to all Context Menus This adds tooltips to all context menus. In particular, there are now tooltips available that describe the functionality of each component. --- src/css/RunEditor.scss | 2 - src/css/Tooltip.scss | 11 ++- src/ui/LayoutEditor.tsx | 153 ++++++++++++++++++++++++------------- src/ui/RunEditor.tsx | 66 ++++++++++++---- src/ui/SplitsSelection.tsx | 10 ++- 5 files changed, 170 insertions(+), 72 deletions(-) diff --git a/src/css/RunEditor.scss b/src/css/RunEditor.scss index d33c2e2..cfd3f17 100644 --- a/src/css/RunEditor.scss +++ b/src/css/RunEditor.scss @@ -209,14 +209,12 @@ $small-button-padding: 1px 3px 1px 3px; cursor: pointer; div { - width: 100%; height: $segment-icon-size; .segment-icon { width: 100%; height: 100%; object-fit: contain; - object-position: 100% 50%; } } } diff --git a/src/css/Tooltip.scss b/src/css/Tooltip.scss index 1559df3..2406ce0 100644 --- a/src/css/Tooltip.scss +++ b/src/css/Tooltip.scss @@ -3,7 +3,6 @@ .tooltip { position: relative; - display: inline-block; } .tooltip .tooltip-text { @@ -22,7 +21,8 @@ margin-left: -150px; opacity: 0; transition: opacity 0.25s; - transition-delay: 0.5s; + transition-delay: 0.25s; + text-wrap: initial; @include mobile { left: 0; @@ -30,6 +30,13 @@ } } +.react-contextmenu-item.tooltip .tooltip-text { + bottom: initial; + left: calc(100% + $ui-margin); + margin-left: 0; + top: 0; +} + .tooltip:hover .tooltip-text { visibility: visible; opacity: 1; diff --git a/src/ui/LayoutEditor.tsx b/src/ui/LayoutEditor.tsx index eb5450c..417c937 100644 --- a/src/ui/LayoutEditor.tsx +++ b/src/ui/LayoutEditor.tsx @@ -138,57 +138,110 @@ export class LayoutEditor extends React.Component { - this.addComponent(LiveSplit.CurrentComparisonComponent)}> - Current Comparison - - this.addComponent(LiveSplit.CurrentPaceComponent)}> - Current Pace - - this.addComponent(LiveSplit.DeltaComponent)}> - Delta - - this.addComponent(LiveSplit.DetailedTimerComponent)}> - Detailed Timer - - this.addComponent(LiveSplit.GraphComponent)}> - Graph - - this.addComponent(LiveSplit.PbChanceComponent)}> - PB Chance - - this.addComponent(LiveSplit.PossibleTimeSaveComponent)}> - Possible Time Save - - this.addComponent(LiveSplit.PreviousSegmentComponent)}> - Previous Segment - - this.addComponent(LiveSplit.SegmentTimeComponent)}> - Segment Time - - this.addComponent(LiveSplit.SplitsComponent)}> - Splits - - this.addComponent(LiveSplit.SumOfBestComponent)}> - Sum of Best Segments - - this.addComponent(LiveSplit.TextComponent)}> - Text - - this.addComponent(LiveSplit.TimerComponent)}> - Timer - - this.addComponent(LiveSplit.TitleComponent)}> + this.addComponent(LiveSplit.TitleComponent)}> Title + + Shows the name of the game and the category that is being run. Additionally, the game icon, the attempt count, and the total number of successfully finished runs can be shown. + - this.addComponent(LiveSplit.TotalPlaytimeComponent)}> - Total Playtime + this.addComponent(LiveSplit.GraphComponent)}> + Graph + + Visualizes how far the current run has been ahead or behind the chosen comparison throughout the whole run. All the individual deltas are shown as points in a graph. + + + this.addComponent(LiveSplit.SplitsComponent)}> + Splits + + The main component for visualizing all the split times. Each segment is shown in a tabular fashion showing the segment icon, segment name, the delta compared to the chosen comparison, and the split time. The list provides scrolling functionality, so not every segment needs to be shown all the time. + - this.addComponent(LiveSplit.BlankSpaceComponent)}> - Blank Space + this.addComponent(LiveSplit.DetailedTimerComponent)}> + Detailed Timer + + Shows two timers, one for the total time of the current run and one showing the time of just the current segment. Other information, like segment times of up to two comparisons, the segment icon, and the segment's name, can also be shown. + - this.addComponent(LiveSplit.SeparatorComponent)}> + this.addComponent(LiveSplit.TimerComponent)}> + Timer + + Shows the total time of the current run as a digital clock. The color of the time shown is based on a how well the current run is doing compared to the chosen comparison. + + + + this.addComponent(LiveSplit.CurrentComparisonComponent)}> + Current Comparison + + Shows the name of the comparison that the timer is currently comparing against. + + + this.addComponent(LiveSplit.CurrentPaceComponent)}> + Current Pace + + Shows a prediction of the current run's final time. The remainder of the run is predicted based on the chosen comparison for the component. + + + this.addComponent(LiveSplit.DeltaComponent)}> + Delta + + Shows how far ahead or behind the current run is compared to the chosen comparison. + + + this.addComponent(LiveSplit.PbChanceComponent)}> + PB Chance + + Shows how likely it is to beat the personal best. If there is no active run, it shows the general chance of beating the personal best. During a run it actively changes based on how well the run is going. + + + this.addComponent(LiveSplit.PossibleTimeSaveComponent)}> + Possible Time Save + + Shows how much time you can save on the current segment compared to the chosen comparison, based on the best segment time of the segment. This component also allows showing the "Total Possible Time Save" for the remainder of the current run. + + + this.addComponent(LiveSplit.PreviousSegmentComponent)}> + Previous Segment + + Shows how much time was saved or lost during the previous segment based on the chosen comparison. Additionally, the potential time save for the previous segment can be displayed. This component switches to a "Live Segment" view that shows the active time loss whenever you are losing time on the current segment. + + + this.addComponent(LiveSplit.SegmentTimeComponent)}> + Segment Time + + Shows the time for the current segment in a comparison of your choosing. If no comparison is specified it uses the timer's current comparison. + + + this.addComponent(LiveSplit.SumOfBestComponent)}> + Sum of Best Segments + + Shows the fastest possible time to complete a run of the current category, based on information collected from all the previous runs. This often matches up with the sum of the best segment times of all the segments, but that may not always be the case, as skipped segments may introduce combined segments that may be faster than the actual sum of their best segment times. The name is therefore a bit misleading, but sticks around for historical reasons. + + + this.addComponent(LiveSplit.TextComponent)}> + Text + + Shows the text that you specify. This can either be a single centered text, or split up into a left and right text, which is suitable for a situation where you have a label and a value. There is also the option of showing a custom variable that you specify in the splits editor. + + + this.addComponent(LiveSplit.TotalPlaytimeComponent)}> + Total Playtime + + Shows the total amount of time that the current category has been played for. + + + + this.addComponent(LiveSplit.BlankSpaceComponent)}> + Blank Space + + An empty component that doesn't show anything other than a background. It mostly serves as padding between other components. + + + this.addComponent(LiveSplit.SeparatorComponent)}> Separator + + A simple component that only serves to render separators between components. + - this.clearHistory()}> - Clear History + this.clearHistory()}> + Clear Only History + + Splits store the entire history of all runs, including every split time. This information is used by various components. You can clear the history with this. The personal best, the best segment times, and the comparisons will not be affected. + - this.clearTimes()}> - Clear Times + this.clearTimes()}> + Clear All Times + + This removes all the times from the splits, including all the history, such that they are completely empty, as if they were just created. + - this.cleanSumOfBest()}> + this.cleanSumOfBest()}> Clean Sum of Best + + Allows you to interactively remove potential issues in the segment history that lead to an inaccurate Sum of Best. If you skip a split, whenever you will do the next split, the combined segment time might be faster than the sum of the individual best segments. This will point out all of these and allows you to delete them individually if any of them seem wrong. + - this.generateGoalComparison()}> + this.generateGoalComparison()}> Generate Goal Comparison + + Generates a custom goal comparison based on a goal time that you can specify. The comparison's times are automatically balanced based on the segment history such that it roughly represents what the split times for the goal time would look like. Since it is populated by the segment history, only goal times within the sum of the best segments and the sum of the worst segments are supported. Everything else is automatically capped by that range. The comparison is only populated for the selected timing method. The other timing method's comparison times are not modified by this, so you can generate it again with the other timing method to generate the comparison times for both timing methods. + @@ -1193,15 +1217,21 @@ export class RunEditor extends React.Component { {comparison} - + this.renameComparison(comparison) }> Rename + + Choose a new name for the custom comparison. There are reserved names that can't be used. You also can't have duplicate names. + - + this.removeComparison(comparison) }> Remove + + Removes the custom comparison. + @@ -1256,11 +1286,17 @@ export class RunEditor extends React.Component { } - this.changeSegmentIcon(segmentIndex)}> + this.changeSegmentIcon(segmentIndex)}> Set Icon + + Allows you to choose an image file to set as the segment's icon. Certain file formats may not work everywhere. + - this.removeSegmentIcon(segmentIndex)}> + this.removeSegmentIcon(segmentIndex)}> Remove Icon + + Removes the segment's icon. + diff --git a/src/ui/SplitsSelection.tsx b/src/ui/SplitsSelection.tsx index 42302dc..bbb2b48 100644 --- a/src/ui/SplitsSelection.tsx +++ b/src/ui/SplitsSelection.tsx @@ -140,12 +140,18 @@ export class SplitsSelection extends React.Component { - this.exportSplits(key, info)}> + this.exportSplits(key, info)}> Export to File + + Export the splits to a file on your computer. + { - this.props.generalSettings.splitsIoIntegration && this.uploadSplitsToSplitsIO(key)}> + this.props.generalSettings.splitsIoIntegration && this.uploadSplitsToSplitsIO(key)}> Upload to Splits.io + + Upload the splits to splits.io. + } From d82c89654cb0b333a212cc7f6d6f1157e889a3d9 Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Sat, 25 May 2024 18:55:46 +0200 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: wooferzfg --- src/ui/LayoutEditor.tsx | 12 ++++++------ src/ui/RunEditor.tsx | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ui/LayoutEditor.tsx b/src/ui/LayoutEditor.tsx index 417c937..0f35a52 100644 --- a/src/ui/LayoutEditor.tsx +++ b/src/ui/LayoutEditor.tsx @@ -147,7 +147,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.GraphComponent)}> Graph - Visualizes how far the current run has been ahead or behind the chosen comparison throughout the whole run. All the individual deltas are shown as points in a graph. + Visualizes how far the current run has been ahead or behind the chosen comparison throughout the whole run. All the individual deltas are shown as points on the graph. this.addComponent(LiveSplit.SplitsComponent)}> @@ -160,7 +160,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.DetailedTimerComponent)}> Detailed Timer - Shows two timers, one for the total time of the current run and one showing the time of just the current segment. Other information, like segment times of up to two comparisons, the segment icon, and the segment's name, can also be shown. + Shows two timers, one for the total time of the current run and one showing the time of just the current segment. Other information, like segment times of up to two comparisons, the segment icon, and the segment name, can also be shown. this.addComponent(LiveSplit.TimerComponent)}> @@ -179,7 +179,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.CurrentPaceComponent)}> Current Pace - Shows a prediction of the current run's final time. The remainder of the run is predicted based on the chosen comparison for the component. + Shows a prediction for the current run's final time. The remainder of the run is predicted based on the chosen comparison for the component. For example, the "Best Segments" comparison can be chosen to show the best possible final time for the current run based on the Sum of Best Segments. this.addComponent(LiveSplit.DeltaComponent)}> @@ -191,7 +191,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.PbChanceComponent)}> PB Chance - Shows how likely it is to beat the personal best. If there is no active run, it shows the general chance of beating the personal best. During a run it actively changes based on how well the run is going. + Shows how likely it is for the active run to beat the personal best. If there is no active run, it shows the general chance of beating the personal best. During a run, it actively changes based on how well the run is going. this.addComponent(LiveSplit.PossibleTimeSaveComponent)}> @@ -209,7 +209,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.SegmentTimeComponent)}> Segment Time - Shows the time for the current segment in a comparison of your choosing. If no comparison is specified it uses the timer's current comparison. + Shows the time for the current segment for the chosen comparison. If no comparison is specified it uses the timer's current comparison. this.addComponent(LiveSplit.SumOfBestComponent)}> @@ -240,7 +240,7 @@ export class LayoutEditor extends React.Component { this.addComponent(LiveSplit.SeparatorComponent)}> Separator - A simple component that only serves to render separators between components. + A simple component that just renders a separator between components. diff --git a/src/ui/RunEditor.tsx b/src/ui/RunEditor.tsx index 1deb6d8..80368b2 100644 --- a/src/ui/RunEditor.tsx +++ b/src/ui/RunEditor.tsx @@ -164,7 +164,7 @@ export class RunEditor extends React.Component { this.downloadBoxArt()}> Download Box Art - Attempts to download the box art of the game from speedrun.com. + Attempts to download the box art of the game from speedrun.com, to set as the game's icon. this.downloadIcon()}> @@ -357,25 +357,25 @@ export class RunEditor extends React.Component { this.clearHistory()}> Clear Only History - Splits store the entire history of all runs, including every split time. This information is used by various components. You can clear the history with this. The personal best, the best segment times, and the comparisons will not be affected. + Splits store the entire history of all runs, including every segment time. This information is used by various components. You can clear the history with this. The personal best, the best segment times, and the comparisons will not be affected. this.clearTimes()}> Clear All Times - This removes all the times from the splits, including all the history, such that they are completely empty, as if they were just created. + This removes all the times from the splits, including all the history, such that the splits are completely empty, as if they were just created. this.cleanSumOfBest()}> Clean Sum of Best - Allows you to interactively remove potential issues in the segment history that lead to an inaccurate Sum of Best. If you skip a split, whenever you will do the next split, the combined segment time might be faster than the sum of the individual best segments. This will point out all of these and allows you to delete them individually if any of them seem wrong. + Allows you to interactively remove potential issues in the segment history that lead to an inaccurate Sum of Best. If you skip a split, whenever you will do the next split, the combined segment time might be faster than the sum of the individual best segments. This will point out all such occurrences and allow you to delete them individually if any of them seem wrong. this.generateGoalComparison()}> Generate Goal Comparison - Generates a custom goal comparison based on a goal time that you can specify. The comparison's times are automatically balanced based on the segment history such that it roughly represents what the split times for the goal time would look like. Since it is populated by the segment history, only goal times within the sum of the best segments and the sum of the worst segments are supported. Everything else is automatically capped by that range. The comparison is only populated for the selected timing method. The other timing method's comparison times are not modified by this, so you can generate it again with the other timing method to generate the comparison times for both timing methods. + Generates a custom goal comparison based on a goal time that you can specify. The comparison's times are automatically balanced based on the segment history such that it roughly represents what the split times for the goal time would look like. Since it is populated by the segment history, the goal times are capped to a range between the sum of the best segments and the sum of the worst segments. The comparison is only populated for the selected timing method. The other timing method's comparison times are not modified by this, so you can generate it again with the other timing method to generate the comparison times for both timing methods.