|
1 | 1 | import { PlusIcon, TrashIcon } from "@heroicons/react/24/solid"; |
2 | | -import { FunctionComponent, StrictMode, Suspense, useState } from "react"; |
| 2 | +import { |
| 3 | + ChangeEventHandler, |
| 4 | + FunctionComponent, |
| 5 | + StrictMode, |
| 6 | + Suspense, |
| 7 | + useState, |
| 8 | +} from "react"; |
3 | 9 | import { createRoot } from "react-dom/client"; |
4 | 10 | import { Watch, WatchV2, toWatchlistV2 } from "../watch-list"; |
5 | 11 |
|
@@ -65,45 +71,79 @@ const App: FunctionComponent = () => { |
65 | 71 | Watchlist |
66 | 72 | </div> |
67 | 73 | <p className="text-sm text-zinc-500 dark:text-zinc-400"> |
68 | | - Directories to be watched and uploaded to Gyazo. <br /> |
69 | | - Only upload files that were placed later. |
| 74 | + This is the directory used for uploading to Gyazo. <br /> |
| 75 | + Any files placed in this directory after saving the settings will |
| 76 | + be uploaded automatically. |
| 77 | + </p> |
| 78 | + |
| 79 | + <p className="text-sm text-zinc-500 dark:text-zinc-400"> |
| 80 | + You can also choose to copy the uploaded Gyazo URL to the |
| 81 | + clipboard. |
70 | 82 | </p> |
71 | 83 | </div> |
72 | 84 |
|
73 | 85 | <table className="min-w-full table-fixed border-collapse text-left text-sm/6 text-zinc-950 dark:text-white"> |
74 | 86 | <thead className="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400"> |
75 | 87 | <tr className="border-b border-zinc-200 dark:border-white/10"> |
76 | 88 | <th className="px-0 py-2">Path</th> |
| 89 | + <th className="px-4 py-2 text-center">Clipboard</th> |
77 | 90 | <th className="w-12 px-0 py-2 text-right"></th> |
78 | 91 | </tr> |
79 | 92 | </thead> |
80 | 93 |
|
81 | 94 | <tbody className="divide-y divide-zinc-200 dark:divide-white/10"> |
82 | | - {watchlist.map(({ path }, index) => ( |
83 | | - <tr |
84 | | - key={index} |
85 | | - className="transition hover:bg-zinc-100/60 dark:hover:bg-white/5" |
86 | | - > |
87 | | - <td className="max-w-[18rem] truncate py-3 pr-4 text-sm text-zinc-700 dark:text-zinc-200 sm:max-w-none"> |
88 | | - {path} |
89 | | - </td> |
90 | | - <td className="py-3 text-right"> |
91 | | - <button |
92 | | - type="button" |
93 | | - className="inline-flex size-9 items-center justify-center rounded-md text-zinc-500 transition hover:text-zinc-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:text-zinc-400 dark:hover:text-white" |
94 | | - onClick={() => { |
95 | | - setWatchlist((prevWatchlist) => [ |
96 | | - ...prevWatchlist.slice(0, index), |
97 | | - ...prevWatchlist.slice(index + 1), |
98 | | - ]); |
99 | | - }} |
100 | | - > |
101 | | - <TrashIcon className="size-4" /> |
102 | | - <span className="sr-only">Remove</span> |
103 | | - </button> |
104 | | - </td> |
105 | | - </tr> |
106 | | - ))} |
| 95 | + {watchlist.map((watch, index) => { |
| 96 | + const handleClipboardCheckboxChange: ChangeEventHandler< |
| 97 | + HTMLInputElement |
| 98 | + > = (event) => { |
| 99 | + setWatchlist((prev) => { |
| 100 | + const watchlist = [...prev]; |
| 101 | + watchlist[index] = { |
| 102 | + ...watchlist[index], |
| 103 | + writesClipboard: event.target.checked, |
| 104 | + }; |
| 105 | + return watchlist; |
| 106 | + }); |
| 107 | + }; |
| 108 | + |
| 109 | + const handleRemoveButtonClick = () => { |
| 110 | + setWatchlist((prev) => [ |
| 111 | + ...prev.slice(0, index), |
| 112 | + ...prev.slice(index + 1), |
| 113 | + ]); |
| 114 | + }; |
| 115 | + |
| 116 | + return ( |
| 117 | + <tr |
| 118 | + key={index} |
| 119 | + className="transition hover:bg-zinc-100/60 dark:hover:bg-white/5" |
| 120 | + > |
| 121 | + <td className="max-w-[18rem] truncate py-3 pr-4 text-sm text-zinc-700 dark:text-zinc-200 sm:max-w-none"> |
| 122 | + {watch.path} |
| 123 | + </td> |
| 124 | + |
| 125 | + <td className="px-4 py-3 text-center"> |
| 126 | + <input |
| 127 | + type="checkbox" |
| 128 | + checked={watch.writesClipboard ?? false} |
| 129 | + onChange={handleClipboardCheckboxChange} |
| 130 | + className="size-4 shrink-0 rounded border border-zinc-950/15 text-blue-600 accent-blue-600 transition focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:border-white/20 dark:bg-white/5 dark:accent-blue-400" |
| 131 | + /> |
| 132 | + </td> |
| 133 | + |
| 134 | + <td className="py-3 text-right"> |
| 135 | + <button |
| 136 | + type="button" |
| 137 | + className="inline-flex size-9 items-center justify-center rounded-md text-zinc-500 transition hover:text-zinc-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500 dark:text-zinc-400 dark:hover:text-white" |
| 138 | + onClick={handleRemoveButtonClick} |
| 139 | + > |
| 140 | + <TrashIcon className="size-4" /> |
| 141 | + <span className="sr-only">Remove</span> |
| 142 | + </button> |
| 143 | + </td> |
| 144 | + </tr> |
| 145 | + ); |
| 146 | + })} |
107 | 147 | </tbody> |
108 | 148 | </table> |
109 | 149 |
|
|
0 commit comments