Skip to content

Commit

Permalink
fix(Timers): alert sound failure, close window on start pref (#13457)
Browse files Browse the repository at this point in the history
* fix(Timers): alert sound failure, close window on start pref

* Update CHANGELOG.md

* Update CHANGELOG.md and optimise images

---------

Co-authored-by: Milena Araujo <mil3na@users.noreply.github.com>
Co-authored-by: raycastbot <bot@raycast.com>
  • Loading branch information
3 people committed Jul 16, 2024
1 parent cdd567d commit 0f37f67
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 155 deletions.
8 changes: 8 additions & 0 deletions extensions/timers/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Timers Changelog

## [Bugfixes and improvements] - 2024-07-16

- Fix bug where alert sound would not play if osascript notification command failed due to lack of permissions
- Fix bug where quicklink-root-presets would not close properly if "Automatically close window on start" was disabled
- Add icons to "Manage Timers" and "Manage Stopwatches" command actions
- Various code improvements

## [Persistent commands, codebase cleanup] - 2024-05-19

- Add preference to keep "Manage Timers" and "Manage Stopwatches" commands open on timer/stopwatch start
- Various refactors around the codebase

Expand Down
72 changes: 33 additions & 39 deletions extensions/timers/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions extensions/timers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -317,14 +317,14 @@
}
],
"dependencies": {
"@raycast/api": "^1.65.1"
"@raycast/api": "^1.78.1"
},
"devDependencies": {
"@raycast/eslint-config": "^1.0.8",
"@types/node": "~20.11.5",
"@types/react": "^18.2.48",
"@types/node": "~20.14.10",
"@types/react": "^18.3.3",
"eslint": "^8.56.0",
"typescript": "^5.3.3"
"typescript": "^5.5.3"
},
"scripts": {
"build": "ray build -e dist",
Expand Down
3 changes: 1 addition & 2 deletions extensions/timers/src/backend/stopwatchBackend.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { environment, popToRoot } from "@raycast/api";
import { environment } from "@raycast/api";
import { execSync } from "child_process";
import { randomUUID } from "crypto";
import { existsSync, readdirSync, readFileSync, writeFileSync } from "fs";
Expand Down Expand Up @@ -56,7 +56,6 @@ const startStopwatch = async ({ swName = "Untitled", launchedFromMenuBar = false
swStore.push(newTimer);
writeFileSync(SWPATH, JSON.stringify(swStore));

popToRoot();
showHudOrToast({ msg: `Stopwatch "${swName}" started!`, launchedFromMenuBar: launchedFromMenuBar, isErr: false });
};

Expand Down
2 changes: 1 addition & 1 deletion extensions/timers/src/backend/timerBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async function startTimer({
cmdParts.push(`while [ -f "${dismissFile}" ]; do ${afplayString}; done`);
}
cmdParts.push(`rm "${masterName}"; else echo "Timer deleted"; fi`);
exec(cmdParts.join(" && "), (error, stderr) => {
exec(cmdParts.join(" ; "), (error, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
Expand Down
53 changes: 53 additions & 0 deletions extensions/timers/src/components/CustomTimerListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Action, ActionPanel, Icon, List } from "@raycast/api";
import { CommandLinkParams, CustomTimer } from "../backend/types";
import { formatTime } from "../backend/formatUtils";
import useTimers from "../hooks/useTimers";
import RenameAction from "./RenameAction";

const createPresetLink = (ctID: string): string => {
const payload: CommandLinkParams = { timerID: ctID };
const encodedPayload = encodeURIComponent(JSON.stringify(payload));
return `raycast://extensions/ThatNerd/timers/manageTimers?context=${encodedPayload}`;
};

export default function CustomTimerListItem(props: { customTimer: CustomTimer; id: string }) {
const { handleStartCT, handleDeleteCT } = useTimers();
return (
<List.Item
icon={Icon.Clock}
title={props.customTimer.name}
subtitle={formatTime(props.customTimer.timeInSeconds)}
actions={
<ActionPanel>
<Action
title="Start Timer"
icon={Icon.Hourglass}
onAction={() => handleStartCT({ customTimer: props.customTimer })}
/>
<RenameAction
renameLabel="Timer"
currentName={props.customTimer.name}
originalFile={"customTimer"}
ctID={props.id}
/>
<Action
title="Delete Custom Timer"
icon={Icon.Trash}
shortcut={{
modifiers: ["ctrl"],
key: "x",
}}
onAction={() => handleDeleteCT(props.id)}
/>
<Action.CreateQuicklink
quicklink={{
name: props.customTimer.name,
link: createPresetLink(props.id),
}}
title="Add Preset to Root Search"
/>
</ActionPanel>
}
/>
);
}
20 changes: 20 additions & 0 deletions extensions/timers/src/components/RenameAction.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Action, Icon, useNavigation } from "@raycast/api";
import { RenameView, RenameViewProps } from "./RenameView";

interface RenameActionProps extends RenameViewProps {
renameLabel: string;
}

export default function RenameAction(props: RenameActionProps) {
const { push } = useNavigation();

return (
<Action
title={`Rename ${props.renameLabel}`}
icon={Icon.TextInput}
onAction={() =>
push(<RenameView currentName={props.currentName} originalFile={props.originalFile} ctID={props.ctID} />)
}
/>
);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import { Action, ActionPanel, Form, popToRoot, Toast } from "@raycast/api";
import { renameStopwatch } from "./backend/stopwatchBackend";
import { renameCustomTimer, renameTimer } from "./backend/timerBackend";
import { Action, ActionPanel, Form, Toast, useNavigation } from "@raycast/api";
import { renameStopwatch } from "../backend/stopwatchBackend";
import { renameCustomTimer, renameTimer } from "../backend/timerBackend";
import { showHudOrToast } from "../backend/utils";

export default function RenameView(props: { currentName: string; originalFile: string; ctID: string | null }) {
interface RenameViewProps {
currentName: string;
originalFile: string;
ctID: string | null;
}

function RenameView(props: RenameViewProps) {
const { pop } = useNavigation();
const handleSubmit = (newName: string) => {
if (newName === "" || newName === props.currentName) {
const toast = new Toast({ style: Toast.Style.Failure, title: "No new name given!" });
toast.show();
} else {
popToRoot();
pop();
switch (props.originalFile) {
case "customTimer":
renameCustomTimer(props.ctID ? props.ctID : "-99", newName);
Expand All @@ -20,8 +28,8 @@ export default function RenameView(props: { currentName: string; originalFile: s
renameTimer(props.originalFile, newName);
break;
}
const toast = new Toast({ style: Toast.Style.Success, title: `Renamed to ${newName}!` });
toast.show();

showHudOrToast({ msg: `Renamed to ${newName}!`, launchedFromMenuBar: false, isErr: false });
}
};

Expand All @@ -37,3 +45,5 @@ export default function RenameView(props: { currentName: string; originalFile: s
</Form>
);
}

export { type RenameViewProps, RenameView };
43 changes: 43 additions & 0 deletions extensions/timers/src/components/RunningTimerListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Action, ActionPanel, Color, Icon, List } from "@raycast/api";
import { Timer } from "../backend/types";
import { formatDateTime, formatTime } from "../backend/formatUtils";
import useTimers from "../hooks/useTimers";
import RenameAction from "./RenameAction";

interface RunningTimerListItemProps {
timer: Timer;
}

const runningLabel = { tag: { value: "Running", color: Color.Yellow } };
const finishedLabel = { tag: { value: "Finished!", color: Color.Green } };

export default function RunningTimerListItem({ timer }: RunningTimerListItemProps) {
const { handleStopTimer, handleCreateCT } = useTimers();
return (
<List.Item
icon={{ source: Icon.Clock, tintColor: timer.timeLeft === 0 ? Color.Green : Color.Yellow }}
title={timer.name}
subtitle={formatTime(timer.timeLeft) + " left"}
accessories={[
{ text: formatTime(timer.secondsSet) + " originally" },
{ text: `${timer.timeLeft === 0 ? "Ended" : "Ends"} at ${formatDateTime(timer.timeEnds)}` },
timer.timeLeft === 0 ? finishedLabel : runningLabel,
]}
actions={
<ActionPanel>
<Action title="Stop Timer" icon={Icon.Stop} onAction={() => handleStopTimer(timer)} />
<RenameAction renameLabel={"Timer"} currentName={timer.name} originalFile={timer.originalFile} ctID={null} />
<Action
title="Save Timer as Preset"
icon={Icon.SaveDocument}
shortcut={{
modifiers: ["cmd", "shift"],
key: "enter",
}}
onAction={() => handleCreateCT(timer)}
/>
</ActionPanel>
}
/>
);
}
Loading

0 comments on commit 0f37f67

Please sign in to comment.