Skip to content

Commit 285b0c1

Browse files
authored
Merge pull request #20 from lirena00/new_update
update v1.4.0
2 parents f0038bd + 18f31b9 commit 285b0c1

File tree

13 files changed

+666
-481
lines changed

13 files changed

+666
-481
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "monochromate",
33
"description": "An extension that greyscales the webpage to reduce doomscrolling",
44
"private": true,
5-
"version": "1.3.2",
5+
"version": "1.4.0",
66
"type": "module",
77
"scripts": {
88
"dev": "wxt",

src/components/BackupCard.tsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Upload, Download, Check } from "lucide-react";
2+
import { useState } from "react";
3+
4+
export default function Backup() {
5+
const handleExport = async () => {
6+
try {
7+
const data = await browser.storage.local.get("Monofilter");
8+
const settings = data.Monofilter;
9+
10+
if (settings) {
11+
const exportData = {
12+
version: browser.runtime.getManifest().version,
13+
timestamp: new Date().toISOString(),
14+
settings: settings,
15+
};
16+
17+
const blob = new Blob([JSON.stringify(exportData, null, 2)], {
18+
type: "application/json",
19+
});
20+
const url = URL.createObjectURL(blob);
21+
const a = document.createElement("a");
22+
a.href = url;
23+
a.download = `monochromate-settings-backup.json`;
24+
a.click();
25+
URL.revokeObjectURL(url);
26+
}
27+
} catch (error) {
28+
console.error("Export failed:", error);
29+
}
30+
};
31+
const handleImport = () => {
32+
const input = document.createElement("input");
33+
input.type = "file";
34+
input.accept = ".json";
35+
input.onchange = async (e) => {
36+
const file = (e.target as HTMLInputElement).files?.[0];
37+
if (!file) return;
38+
39+
try {
40+
const text = await file.text();
41+
const importData = JSON.parse(text);
42+
43+
if (importData.settings) {
44+
await browser.storage.local.set({ Monofilter: importData.settings });
45+
console.log("Settings imported successfully");
46+
}
47+
} catch (error) {
48+
console.error("Import failed:", error);
49+
}
50+
};
51+
input.click();
52+
};
53+
54+
return (
55+
<div className="bg-neutral-100 border-neutral-300 border rounded-xl p-4 hover:border-neutral-400 transition-all">
56+
<div className="flex items-center gap-3 mb-3">
57+
<div className="text-neutral-700">
58+
<Upload size={20} />
59+
</div>
60+
<div>
61+
<h2 className="font-semibold text-neutral-800">Backup Settings</h2>
62+
<p className="text-sm text-neutral-500 italic">
63+
Export or import your configuration
64+
</p>
65+
</div>
66+
</div>
67+
68+
<div className="flex gap-2">
69+
<button
70+
onClick={handleExport}
71+
className="flex-1 flex items-center justify-center gap-2 px-3 py-2 bg-neutral-100 border border-neutral-300 rounded-lg text-sm hover:bg-neutral-200 transition-colors"
72+
>
73+
<Download size={15} />
74+
Export
75+
</button>
76+
<button
77+
onClick={handleImport}
78+
className="flex-1 flex items-center justify-center gap-2 px-3 py-2 bg-neutral-100 border border-neutral-300 rounded-lg text-sm hover:bg-neutral-200 transition-colors"
79+
>
80+
<Upload size={15} />
81+
Import
82+
</button>
83+
</div>
84+
</div>
85+
);
86+
}

src/components/BlacklistCard.tsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import React from "react";
2+
import { Shield } from "lucide-react";
3+
4+
interface BlacklistCardCardProps {
5+
currentUrl: string;
6+
blacklist: string[];
7+
isCurrentUrlBlacklisted: boolean;
8+
onAddCurrentSite: () => void;
9+
onRemoveSite: (site: string) => void;
10+
onManageAllSites: () => void;
11+
}
12+
13+
const BlacklistCardCard: React.FC<BlacklistCardCardProps> = ({
14+
currentUrl,
15+
blacklist,
16+
isCurrentUrlBlacklisted,
17+
onAddCurrentSite,
18+
onRemoveSite,
19+
onManageAllSites,
20+
}) => {
21+
return (
22+
<div className="bg-neutral-100 border-neutral-300 border rounded-xl p-4 hover:border-neutral-400 transition-all">
23+
<div className="flex items-center justify-between mb-3">
24+
<div className="flex items-center gap-3">
25+
<div className="text-neutral-700">
26+
<Shield size={20} />
27+
</div>
28+
<div>
29+
<h2 className="font-semibold text-neutral-800">
30+
Excluded Sites
31+
{blacklist.length > 0 && (
32+
<span className="ml-2 px-2 py-0.5 text-xs bg-neutral-200 rounded-full">
33+
{blacklist.length}
34+
</span>
35+
)}
36+
</h2>
37+
<p className="text-sm text-neutral-500 italic">Manage exceptions</p>
38+
</div>
39+
</div>
40+
</div>
41+
42+
<div className="bg-white rounded-lg border border-neutral-200 p-3 flex justify-between items-center">
43+
<div className="flex items-center gap-2">
44+
<div className="w-4 h-4 bg-neutral-200 rounded-full overflow-hidden">
45+
{currentUrl && (
46+
<img
47+
src={`https://www.google.com/s2/favicons?domain=${currentUrl}&sz=64`}
48+
alt=""
49+
className="w-full h-full object-cover"
50+
/>
51+
)}
52+
</div>
53+
<span className="text-sm font-medium truncate max-w-[180px]">
54+
{currentUrl}
55+
</span>
56+
</div>
57+
58+
{isCurrentUrlBlacklisted ? (
59+
<button
60+
onClick={() => onRemoveSite(currentUrl)}
61+
className="text-xs px-2 py-1 bg-neutral-200 text-neutral-700 rounded-sm hover:bg-neutral-300 transition-colors"
62+
>
63+
Remove
64+
</button>
65+
) : (
66+
<button
67+
onClick={onAddCurrentSite}
68+
className="text-xs px-2 py-1 bg-neutral-900 text-white rounded-sm hover:bg-neutral-800 transition-colors"
69+
>
70+
Exclude
71+
</button>
72+
)}
73+
</div>
74+
75+
<button
76+
onClick={onManageAllSites}
77+
className="mt-3 w-full text-sm flex items-center justify-center gap-2 py-2 transition-colors rounded-lg bg-neutral-900 text-neutral-50 hover:bg-neutral-800 active:bg-neutral-950"
78+
>
79+
Manage all excluded sites
80+
</button>
81+
</div>
82+
);
83+
};
84+
85+
export default BlacklistCardCard;
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import React from "react";
2+
import { ArrowLeft, Search, AlertCircle, X } from "lucide-react";
3+
import Footer from "./Footer";
4+
5+
interface BlacklistManagementProps {
6+
searchTerm: string;
7+
currentUrl: string;
8+
filteredBlacklist: string[];
9+
isCurrentUrlBlacklisted: boolean;
10+
onSearchChange: (value: string) => void;
11+
onReturnToMain: () => void;
12+
onAddCurrentSite: () => void;
13+
onRemoveSite: (site: string) => void;
14+
}
15+
16+
const BlacklistManagement: React.FC<BlacklistManagementProps> = ({
17+
searchTerm,
18+
currentUrl,
19+
filteredBlacklist,
20+
isCurrentUrlBlacklisted,
21+
onSearchChange,
22+
onReturnToMain,
23+
onAddCurrentSite,
24+
onRemoveSite,
25+
}) => {
26+
return (
27+
<div className="flex flex-col min-h-[700px]">
28+
<div className="flex items-center gap-3 mb-4">
29+
<button
30+
onClick={onReturnToMain}
31+
className="p-1 rounded-full hover:bg-neutral-100"
32+
>
33+
<ArrowLeft size={18} />
34+
</button>
35+
<h1 className="text-xl font-bold">Manage Excluded Sites</h1>
36+
</div>
37+
38+
<div className="relative mb-3">
39+
<div className="absolute left-3 top-1/2 -translate-y-1/2 text-neutral-500">
40+
<Search size={15} />
41+
</div>
42+
<input
43+
type="text"
44+
className="w-full pl-9 pr-3 py-2 bg-white border border-neutral-200 rounded-lg text-sm"
45+
placeholder="Search excluded sites..."
46+
value={searchTerm}
47+
onChange={(e) => onSearchChange(e.target.value)}
48+
autoFocus
49+
/>
50+
</div>
51+
52+
<div className="mb-4">
53+
<h2 className="text-sm font-medium text-neutral-500 mb-2">
54+
Current Site
55+
</h2>
56+
<div className="bg-white rounded-lg border border-neutral-200 p-3 flex justify-between items-center">
57+
<div className="flex items-center gap-2">
58+
<div className="w-5 h-5 bg-neutral-200 rounded-full overflow-hidden">
59+
{currentUrl && (
60+
<img
61+
src={`https://www.google.com/s2/favicons?domain=${currentUrl}&sz=64`}
62+
alt=""
63+
className="w-full h-full object-cover"
64+
/>
65+
)}
66+
</div>
67+
<span className="text-sm font-medium truncate max-w-[200px]">
68+
{currentUrl}
69+
</span>
70+
</div>
71+
72+
{isCurrentUrlBlacklisted ? (
73+
<button
74+
onClick={() => onRemoveSite(currentUrl)}
75+
className="text-sm px-3 py-1 bg-neutral-200 text-neutral-700 rounded-sm hover:bg-neutral-300 transition-colors"
76+
>
77+
Remove
78+
</button>
79+
) : (
80+
<button
81+
onClick={onAddCurrentSite}
82+
className="text-sm px-3 py-1 bg-neutral-900 text-white rounded-sm hover:bg-neutral-800 transition-colors flex items-center gap-1"
83+
>
84+
Exclude
85+
</button>
86+
)}
87+
</div>
88+
</div>
89+
90+
<div className="flex-1 overflow-hidden flex flex-col min-h-0">
91+
<h2 className="text-sm font-medium text-neutral-500 mb-2">
92+
All Excluded Sites
93+
</h2>
94+
<div className="flex-1 overflow-y-auto bg-white rounded-lg border border-neutral-200">
95+
{filteredBlacklist.length > 0 ? (
96+
filteredBlacklist.map((site) => (
97+
<div
98+
key={site}
99+
className="flex justify-between items-center py-3 px-3 border-b border-neutral-200 last:border-0 hover:bg-neutral-50"
100+
>
101+
<div className="flex items-center gap-2">
102+
<div className="w-5 h-5 bg-neutral-200 rounded-full overflow-hidden">
103+
<img
104+
src={`https://www.google.com/s2/favicons?domain=${site}&sz=64`}
105+
alt=""
106+
className="w-full h-full object-cover"
107+
/>
108+
</div>
109+
<span className="text-sm text-neutral-700">{site}</span>
110+
</div>
111+
<button
112+
onClick={() => onRemoveSite(site)}
113+
className="text-neutral-500 hover:text-red-500"
114+
>
115+
<X size={15} />
116+
</button>
117+
</div>
118+
))
119+
) : (
120+
<div className="py-8 px-3 text-center flex flex-col items-center gap-2">
121+
{searchTerm ? (
122+
<p className="text-sm text-neutral-500">
123+
No results match "{searchTerm}"
124+
</p>
125+
) : (
126+
<>
127+
<div className="text-neutral-400">
128+
<AlertCircle size={15} />
129+
</div>
130+
<p className="text-sm text-neutral-500">
131+
No sites in exclusion list yet
132+
</p>
133+
</>
134+
)}
135+
</div>
136+
)}
137+
</div>
138+
</div>
139+
140+
<Footer />
141+
</div>
142+
);
143+
};
144+
145+
export default BlacklistManagement;

src/components/Footer.tsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React from "react";
2+
import { Heart, Github, ExternalLink } from "lucide-react";
3+
import { Discord } from "@/components/Icons/Discord";
4+
5+
const Footer: React.FC = () => {
6+
return (
7+
<footer className="my-6 ">
8+
<div className="bg-neutral-100 border-neutral-300 border rounded-xl p-4 hover:border-neutral-400 transition-all">
9+
<div className="grid grid-cols-3 gap-2">
10+
<a
11+
href="https://buymeacoffee.com/lirena00"
12+
target="_blank"
13+
rel="noopener noreferrer"
14+
className="bg-white border border-neutral-200 rounded-lg p-3 hover:border-neutral-400 hover:bg-neutral-50 transition-all group flex flex-col items-center gap-1.5"
15+
>
16+
<span className="text-red-500 group-hover:scale-110 transition-transform">
17+
<Heart size={16} />
18+
</span>
19+
<span className="text-xs text-neutral-600 group-hover:text-neutral-800">
20+
Support
21+
</span>
22+
</a>
23+
24+
<a
25+
href="https://discord.gg/pdxMMNGWCU"
26+
target="_blank"
27+
rel="noopener noreferrer"
28+
className="bg-white border border-neutral-200 rounded-lg p-3 hover:border-neutral-400 hover:bg-neutral-50 transition-all group flex flex-col items-center gap-1.5"
29+
>
30+
<span className="text-indigo-500 group-hover:scale-110 transition-transform">
31+
<Discord />
32+
</span>
33+
<span className="text-xs text-neutral-600 group-hover:text-neutral-800">
34+
Discord
35+
</span>
36+
</a>
37+
38+
<a
39+
href="https://github.com/lirena00/monochromate"
40+
target="_blank"
41+
rel="noopener noreferrer"
42+
className="bg-white border border-neutral-200 rounded-lg p-3 hover:border-neutral-400 hover:bg-neutral-50 transition-all group flex flex-col items-center gap-1.5"
43+
>
44+
<span className="text-neutral-700 group-hover:scale-110 transition-transform">
45+
<Github size={16} />
46+
</span>
47+
<span className="text-xs text-neutral-600 group-hover:text-neutral-800">
48+
Github
49+
</span>
50+
</a>
51+
</div>
52+
53+
<div className="mt-3 pt-3 border-t border-neutral-200 text-center">
54+
<span className="text-xs text-neutral-500">
55+
Made with ❤️ by{" "}
56+
<a
57+
href="https://www.lirena.in?ref=monochromate&source=footer"
58+
target="_blank"
59+
rel="noopener noreferrer"
60+
className="text-neutral-700 hover:text-neutral-900 underline decoration-dotted underline-offset-2"
61+
>
62+
lirena00
63+
</a>
64+
</span>
65+
</div>
66+
</div>
67+
</footer>
68+
);
69+
};
70+
71+
export default Footer;

0 commit comments

Comments
 (0)