feat: Add Linear notification list item

This commit is contained in:
2024-01-26 21:22:47 +01:00
parent 0507722ecf
commit 3df827ebd7
17 changed files with 383 additions and 41 deletions

View File

@@ -0,0 +1,88 @@
import { NotificationActions } from "../../../action/NotificationActions";
import { LinearIssuePreview } from "../preview/LinearIssuePreview";
import { getLinearUserAccessory } from "../accessories";
import { Notification } from "../../../notification";
import { LinearIssueNotification } from "../types";
import { MutatePromise } from "@raycast/utils";
import { Page } from "../../../types";
import { List } from "@raycast/api";
interface LinearIssueNotificationListItemProps {
icon: string;
notification: Notification;
linearIssueNotification: LinearIssueNotification;
mutate: MutatePromise<Page<Notification> | undefined>;
}
export function LinearIssueNotificationListItem({
icon,
notification,
linearIssueNotification,
mutate,
}: LinearIssueNotificationListItemProps) {
const subtitle = `${linearIssueNotification.issue.team.name} #${linearIssueNotification.issue.identifier}`;
const state = getLinearIssueStateAccessory(linearIssueNotification.issue.state);
const assignee = getLinearUserAccessory(linearIssueNotification.issue.assignee);
const accessories: List.Item.Accessory[] = [
state,
assignee,
{
date: new Date(linearIssueNotification.updated_at),
tooltip: `Updated at ${linearIssueNotification.updated_at}`,
},
];
return (
<List.Item
key={notification.id}
title={notification.title}
icon={icon}
accessories={accessories}
subtitle={subtitle}
actions={
<NotificationActions
notification={notification}
detailsTarget={<LinearIssuePreview notification={notification} linearIssue={linearIssueNotification.issue} />}
mutate={mutate}
/>
}
/>
);
}
export function getLinearIssueStateAccessory(state: LinearWorkflowState): List.Item.Accessory {
switch (state.type) {
case "Triage":
return {
icon: { source: "linear-issue-triage.svg", tintColor: state.color },
tooltip: state.name,
};
case "Backlog":
return {
icon: { source: "linear-issue-backlog.svg", tintColor: state.color },
tooltip: state.name,
};
case "Unstarted":
return {
icon: { source: "linear-issue-unstarted.svg", tintColor: state.color },
tooltip: state.name,
};
case "Started":
return {
icon: { source: "linear-issue-started.svg", tintColor: state.color },
tooltip: state.name,
};
case "Completed":
return {
icon: { source: "linear-issue-completed.svg", tintColor: state.color },
tooltip: state.name,
};
case "Canceled":
return {
icon: { source: "linear-issue-canceled.svg", tintColor: state.color },
tooltip: state.name,
};
}
}

View File

@@ -0,0 +1,39 @@
import { LinearProjectNotificationListItem } from "./LinearProjectNotificationListItem";
import { LinearIssueNotificationListItem } from "./LinearIssueNotificationListItem";
import { NotificationListItemProps } from "../../../notification";
import { environment } from "@raycast/api";
import { useMemo } from "react";
export function LinearNotificationListItem({ notification, mutate }: NotificationListItemProps) {
const icon = useMemo(() => {
if (environment.appearance === "dark") {
return "linear-logo-light.svg";
}
return "linear-logo-dark.svg";
}, [environment]);
if (notification.metadata.type !== "Linear") return null;
switch (notification.metadata.content.type) {
case "IssueNotification":
return (
<LinearIssueNotificationListItem
icon={icon}
notification={notification}
linearIssueNotification={notification.metadata.content.content}
mutate={mutate}
/>
);
case "ProjectNotification":
return (
<LinearProjectNotificationListItem
icon={icon}
notification={notification}
LinearProjectNotification={notification.metadata.content.content}
mutate={mutate}
/>
);
default:
return null;
}
}

View File

@@ -0,0 +1,53 @@
import { NotificationActions } from "../../../action/NotificationActions";
import { LinearProjectPreview } from "../preview/LinearProjectPreview";
import { getLinearUserAccessory } from "../accessories";
import { Notification } from "../../../notification";
import { LinearProjectNotification } from "../types";
import { MutatePromise } from "@raycast/utils";
import { Page } from "../../../types";
import { List } from "@raycast/api";
interface LinearProjectNotificationListItemProps {
icon: string;
notification: Notification;
linearProjectNotification: LinearProjectNotification;
mutate: MutatePromise<Page<Notification> | undefined>;
}
export function LinearProjectNotificationListItem({
icon,
notification,
linearProjectNotification,
mutate,
}: LinearProjectNotificationListItemProps) {
const subtitle = linearProjectNotification.project.name;
const lead = getLinearUserAccessory(linearProjectNotification.project.lead);
const accessories: List.Item.Accessory[] = [
lead,
{
date: new Date(linearProjectNotification.updated_at),
tooltip: `Updated at ${linearProjectNotification.updated_at}`,
},
];
return (
<List.Item
key={notification.id}
title={notification.title}
icon={icon}
accessories={accessories}
subtitle={subtitle}
actions={
<NotificationActions
notification={notification}
detailsTarget={
<LinearProjectPreview notification={notification} linearProject={linearProjectNotification.issue} />
}
mutate={mutate}
/>
}
/>
);
}