Skip to content

Commit 146bf69

Browse files
committed
plugin: gate deadline option on premium status
1 parent 0a5fc0c commit 146bf69

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

plugin/src/api/domain/user.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type UserInfo = {
2+
isPremium: boolean;
3+
};

plugin/src/api/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { Label } from "@/api/domain/label";
55
import type { Project } from "@/api/domain/project";
66
import type { Section } from "@/api/domain/section";
77
import type { CreateTaskParams, Task, TaskId } from "@/api/domain/task";
8+
import type { UserInfo } from "@/api/domain/user";
89
import type { RequestParams, WebFetcher, WebResponse } from "@/api/fetcher";
910
import debug from "@/log";
1011

@@ -54,6 +55,11 @@ export class TodoistApiClient {
5455
return await this.doPaginated<Label>("/labels");
5556
}
5657

58+
public async getUser(): Promise<UserInfo> {
59+
const response = await this.do("/user", "GET");
60+
return camelize(JSON.parse(response.body)) as UserInfo;
61+
}
62+
5763
private async doPaginated<T>(path: string, params?: Record<string, string>): Promise<T[]> {
5864
const allResults: T[] = [];
5965
let cursor: string | null = null;

plugin/src/data/index.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { Label, LabelId } from "@/api/domain/label";
33
import type { Project, ProjectId } from "@/api/domain/project";
44
import type { Section, SectionId } from "@/api/domain/section";
55
import type { Task as ApiTask, CreateTaskParams, TaskId } from "@/api/domain/task";
6+
import type { UserInfo } from "@/api/domain/user";
67
import { Repository, type RepositoryReader } from "@/data/repository";
78
import { SubscriptionManager, type UnsubscribeCallback } from "@/data/subscriptions";
89
import type { Task } from "@/data/task";
@@ -49,6 +50,7 @@ export class TodoistAdapter {
4950
private readonly subscriptions: SubscriptionManager<Subscription>;
5051

5152
private readonly tasksPendingClose: TaskId[];
53+
private userInfo: UserInfo | undefined;
5254

5355
private hasSynced = false;
5456

@@ -64,6 +66,10 @@ export class TodoistAdapter {
6466
return this.api.hasValue() && this.hasSynced;
6567
}
6668

69+
public isPremium(): boolean {
70+
return this.userInfo?.isPremium ?? true;
71+
}
72+
6773
public async initialize(api: TodoistApiClient) {
6874
this.api.insert(api);
6975
await this.sync();
@@ -74,9 +80,12 @@ export class TodoistAdapter {
7480
return;
7581
}
7682

77-
await this.projects.sync();
78-
await this.sections.sync();
79-
await this.labels.sync();
83+
await Promise.all([
84+
this.syncUserInfo(),
85+
this.projects.sync(),
86+
this.sections.sync(),
87+
this.labels.sync(),
88+
]);
8089

8190
for (const subscription of this.subscriptions.list()) {
8291
await subscription.update();
@@ -85,6 +94,17 @@ export class TodoistAdapter {
8594
this.hasSynced = true;
8695
}
8796

97+
private async syncUserInfo(): Promise<void> {
98+
try {
99+
if (!this.api.hasValue()) {
100+
return;
101+
}
102+
this.userInfo = await this.api.withInner((api) => api.getUser());
103+
} catch (error) {
104+
console.error("Failed to fetch user info:", error);
105+
}
106+
}
107+
88108
public data(): DataAccessor {
89109
return {
90110
projects: this.projects,

plugin/src/ui/createTaskModal/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ const CreateTaskModalContent: React.FC<CreateTaskProps> = ({
173173

174174
const [options, setOptions] = useState<TaskCreationOptions>(initialOptions);
175175

176+
const isPremium = plugin.services.todoist.isPremium();
176177
const isSubmitButtonDisabled = content === "" && options.appendLinkTo !== "content";
177178

178179
const i18n = t().createTaskModal;
@@ -258,7 +259,7 @@ const CreateTaskModalContent: React.FC<CreateTaskProps> = ({
258259
<DueDateSelector selected={dueDate} setSelected={setDueDate} />
259260
<PrioritySelector selected={priority} setSelected={setPriority} />
260261
<LabelSelector selected={labels} setSelected={setLabels} />
261-
<DeadlineSelector selected={deadline} setSelected={setDeadline} />
262+
{isPremium && <DeadlineSelector selected={deadline} setSelected={setDeadline} />}
262263
</div>
263264
<div className="task-creation-selectors-group">
264265
<OptionsSelector selected={options} setSelected={setOptions} />

0 commit comments

Comments
 (0)