Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Commit 62e1265

Browse files
authored
Merge pull request #19 from PSDTools/demo-version
Demo version
2 parents 210a0b4 + 1a9fba9 commit 62e1265

16 files changed

+486
-72
lines changed

.vscode/settings.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"svelte.enable-ts-plugin": true,
33
"eslint.validate": ["typescript", "javascript", "svelte"],
4-
"typescript.tsdk": "node_modules/typescript/lib"
4+
"typescript.tsdk": "node_modules/typescript/lib",
5+
"cSpell.words": [
6+
"Fitz"
7+
]
58
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
"dev": "wxt",
99
"dev:firefox": "wxt -b firefox",
1010
"dev:safari": "wxt -b safari",
11+
"dev:edge": "wxt -b edge",
1112
"build": "wxt build",
1213
"build:firefox": "wxt build -b firefox",
1314
"build:safari": "wxt build -b safari",
15+
"build:edge": "wxt build -b edge",
1416
"zip": "wxt zip",
1517
"zip:firefox": "wxt zip -b firefox",
1618
"zip:safari": "wxt zip -b safari",

src/entrypoints/popup/App.svelte

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,25 @@
77
88
import HomeComponent from "./Home.svelte";
99
import PhishingComponent from "./Phishing.svelte";
10+
import PhishingReal from "./PhishingReal.svelte";
11+
import PhishingMenu from "./PhishingMenu.svelte";
12+
import PhishingLoading from "./PhishingLoading.svelte";
1013
import FactCheckComponent from "./FactCheck.svelte";
1114
import ChatComponent from "./Chat.svelte";
1215
import FactCheckLoadingComponent from "./FactCheckLoading.svelte";
1316
import FactsChecked from "./FactsChecked.svelte";
17+
import FactsCheckedFake from "./FactsCheckedFake.svelte";
1418
1519
const RouteName = {
1620
Home: "home",
1721
Phishing: "phishing",
22+
PhishingReal: "phishing-real",
23+
PhishingMenu: "phishing-menu",
24+
PhishingLoading: "phishing-loading",
1825
FactCheck: "fact-check",
1926
FactCheckLoading: "fact-check-loading",
2027
FactsChecked: "real",
28+
FactsCheckedFake: "fake",
2129
Chat: "chat",
2230
Any: "any",
2331
} as const;
@@ -35,6 +43,21 @@
3543
path: `/${RouteName.Phishing}`,
3644
component: PhishingComponent,
3745
},
46+
{
47+
name: RouteName.PhishingReal,
48+
path: `/${RouteName.PhishingReal}`,
49+
component: PhishingReal,
50+
},
51+
{
52+
name: RouteName.PhishingMenu,
53+
path: `/${RouteName.PhishingMenu}`,
54+
component: PhishingMenu,
55+
},
56+
{
57+
name: RouteName.PhishingLoading,
58+
path: `/${RouteName.PhishingLoading}`,
59+
component: PhishingLoading,
60+
},
3861
{
3962
name: RouteName.FactCheck,
4063
path: `/${RouteName.FactCheck}`,
@@ -50,19 +73,24 @@
5073
path: `/${RouteName.FactsChecked}`,
5174
component: FactsChecked,
5275
},
76+
5377
{
5478
name: RouteName.Chat,
5579
path: `/${RouteName.Chat}`,
5680
component: ChatComponent,
5781
},
58-
5982
{
6083
name: RouteName.Any,
6184
path: "*",
6285
redirect: {
6386
name: RouteName.Home,
6487
},
6588
},
89+
{
90+
name: RouteName.FactsCheckedFake,
91+
path: `/${RouteName.FactsCheckedFake}`,
92+
component: FactsCheckedFake,
93+
},
6694
] as const satisfies Route<RouteNames>[];
6795
6896
export const options = {

src/entrypoints/popup/Chat.svelte

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
1-
<script lang="ts">
2-
import BlankAnchor from "./BlankAnchor.svelte";
3-
import Wrapper from "./Wrapper.svelte";
4-
import { Send } from "lucide-svelte";
1+
<script lang="ts" module>
52
import { GoogleGenerativeAI } from "@google/generative-ai";
63
74
const key = import.meta.env.VITE_GEMINI_API_KEY;
85
96
const genAI = new GoogleGenerativeAI(key);
10-
// console.log(result.response.text());
7+
8+
const model = genAI.getGenerativeModel({
9+
model: "gemini-2.0-flash-lite",
10+
systemInstruction:
11+
'You are DUCKY and help people with cybersecurity and digital literacy. Always say "Quack!" at the end of every response. Have a playful but serious tone; business casual. DUCKY has a phishing detector, chatbot, and website fact checker. DUCKY is a web extension available on all web browsers. The phishing detector looks at an email and determines if it is phishing attack or legitimate. You are the chatbot, you help users understand information and answer questions. The fact checker checks websites\' data, finds similar articles to determine if the website is trustworthy. DUCKY is a rubber duck because computer science often uses rubber duckies to talk to, Ducky also stands Defending and Understanding Cybersecurity Knowledge Year-round. Be friendly, no cursing. Keep your response under 75 words, excluding the word "Quack!" from the count. Do not leave blank lines.',
12+
});
13+
</script>
14+
15+
<script lang="ts">
16+
import BlankAnchor from "./BlankAnchor.svelte";
17+
import Wrapper from "./Wrapper.svelte";
18+
import { Send } from "lucide-svelte";
1119
1220
const parameters = new URLSearchParams(
1321
globalThis.location.hash.split("?")[1],
1422
);
1523
1624
let question = $state<string>(parameters.get("q") ?? "");
17-
// let currentQuestion = $state<string>("");
18-
let response = $state<string>();
25+
let response = $state<string>("");
1926
let loading = $state<boolean>(false);
20-
21-
const model = genAI.getGenerativeModel({
22-
model: "gemini-2.0-flash-lite",
23-
systemInstruction:
24-
'you are DUCKY and have to help people with cybersecurity and digital literacy. always say "Quack!" at the end of every response. Have a playful but serious tone; business casual. DUCKY has a phishing detector, chat bot, and website fact checker. DUCKY is a chrome and firefox web extension. The phishing detector will automatically pop up when the user looks at an email and determines if it is phishing. The chatbot is what you are and can help users understand information or can be used to ask questions. The fact checker checks websites data and finds sources and other places to determine if the website is trustworthy. DUCKY is a rubber duck because computer science often uses rubber duckies to talk to. Be friendly, no cursing. Keep response under 75 words exclude the word "Quack!" from the count. Do not leave blank lines inbetween lines.',
25-
});
2627
</script>
2728

2829
<Wrapper pageTitle="Ducky Chat">
@@ -35,14 +36,12 @@
3536
setTimeout(() => {
3637
void (async () => {
3738
const airesponse = await model.generateContent(question);
38-
console.log(airesponse.response.text());
3939
response = airesponse.response.text();
4040
})();
4141
loading = false;
4242
}, 2000);
4343

4444
loading = true;
45-
// question = "";
4645
event.preventDefault();
4746
}}
4847
>
@@ -95,6 +94,7 @@
9594
all: unset;
9695
outline: revert;
9796
background-color: #e2c100;
97+
color: inherit;
9898
9999
display: inline-flex;
100100
align-items: center;

src/entrypoints/popup/FactCheck.svelte

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949

5050
<style>
5151
.radio-indent {
52-
margin-left: 40px;
52+
margin-left: 24px;
5353
}
5454
5555
.option {
@@ -72,13 +72,19 @@
7272
7373
/* New styles for scaling current tab text without taking more than two lines */
7474
.current-tab-text {
75-
/* Font size scales between 14px and 18px based on the viewport width */
76-
font-size: clamp(14px, 2vw, 18px);
75+
/* Font size scales between 12px and 16px based on the viewport width */
76+
font-size: clamp(12px, 1.8vw, 16px);
7777
overflow: hidden;
78+
text-overflow: ellipsis;
7879
display: -webkit-box;
79-
line-clamp: 2;
80-
display: flex;
81-
flex-direction: column;
80+
-webkit-line-clamp: 2;
81+
-webkit-box-orient: vertical;
82+
word-wrap: break-word;
83+
word-break: break-all; /* Forces breaking at any character */
84+
max-width: 100%;
85+
line-height: 1.3;
86+
margin-top: 2px;
87+
padding-right: 5px;
8288
}
8389
.card {
8490
display: flex;

src/entrypoints/popup/FactCheckLoading.svelte

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import Wrapper from "./Wrapper.svelte";
33
import Loading from "./Loading.svelte";
44
import { delay } from "./utils.ts";
5+
import { onMount } from "svelte";
56
const randomMessages = [
67
"Verifying sources",
78
"Feeding ducks",
@@ -11,14 +12,31 @@
1112
"Gathering the flock",
1213
"Flying the coop",
1314
];
15+
let currentTab = $state<chrome.tabs.Tab>();
16+
var nextPage: string = $state("real");
17+
18+
onMount(async () => {
19+
[currentTab] = await browser.tabs.query({
20+
active: true,
21+
currentWindow: true,
22+
});
23+
24+
if ((currentTab.url ?? "").includes("https://newsroom.cisco.com")) {
25+
nextPage = "real";
26+
} else if ((currentTab.url ?? "").includes("https://theonion.com/")) {
27+
nextPage = "fake";
28+
}
29+
});
1430
</script>
1531

1632
<Wrapper pageTitle="Fact Checker">
1733
<div class="fact-wrapper">
34+
<!-- Implement script here to go to different pages based on url -->
35+
1836
<Loading
1937
loader={async (aborter) => await delay(4550, aborter)}
2038
{randomMessages}
21-
url="real"
39+
url={nextPage}
2240
/>
2341
</div>
2442
</Wrapper>

src/entrypoints/popup/FactsChecked.svelte

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import BlankAnchor from "./BlankAnchor.svelte";
33
import Wrapper from "./Wrapper.svelte";
44
5-
let factuality = $state(96);
5+
let factuality = $state(92);
66
const factual = $derived(factuality > 50);
77
</script>
88

@@ -21,35 +21,45 @@
2121

2222
<span class="factuality">
2323
<!-- 8-ball? -->
24-
{factual ? "Likely true" : "Possibly a falsehood"}
24+
{factual ? "Likely True" : "Likely fake"}
2525
</span>
2626

2727
<details class="details">
2828
<summary>Sources</summary>
2929
<ul>
3030
<li>
3131
<BlankAnchor
32-
href="https://www.wwt.com/press-release/wwt-has-entered-into-a-definitive-agreement-to-acquire-softchoice"
33-
>
34-
Official Press Release
35-
</BlankAnchor>
36-
</li>
37-
<li>
38-
<BlankAnchor
39-
href="https://www.wwt.com/news/wwt-to-buy-softchoice-in-dollar125b-blockbuster-heres-what-to-know"
32+
href="https://www.wwt.com/news/cisco-expands-partnership-with-nvidia-to-accelerate-ai-adoption-in-the-enterprise"
4033
>
4134
Official Blogpost
4235
</BlankAnchor>
4336
</li>
4437
</ul>
4538
</details>
39+
<div class="open">
40+
<!--
41+
So, technically, there isn't a search passed here, just a fragment.
42+
But... the router handles it, so we just do some hacks on the chat page.
43+
-->
44+
<a
45+
class="chat-button"
46+
data-query={JSON.stringify({
47+
q: "How can I fact check sources on my own?",
48+
})}
49+
href="#/chat"
50+
>
51+
How can I fact check sources on my own?
52+
</a>
53+
</div>
4654
</div>
4755
</Wrapper>
4856

4957
<style>
5058
.details {
5159
width: 100%;
5260
61+
padding-left: 2rem;
62+
5363
& summary {
5464
font-size: 1.4rem;
5565
}
@@ -94,4 +104,36 @@
94104
font-size: 0.5em;
95105
text-anchor: middle;
96106
}
107+
.open {
108+
display: flex;
109+
flex-direction: row;
110+
align-items: center;
111+
justify-content: center;
112+
gap: 1rem;
113+
padding: 1rem;
114+
text-align: center;
115+
116+
& > .chat-button {
117+
width: 100%;
118+
background-color: #e2c100;
119+
color: #242424;
120+
transition:
121+
border-color 0.25s,
122+
background-color 0.3s,
123+
transform 0.2s;
124+
125+
border-radius: 8px;
126+
border: 1px solid transparent;
127+
padding: 0.6em 1.2em;
128+
font-size: 1em;
129+
font-weight: 500;
130+
font-family: inherit;
131+
cursor: pointer;
132+
133+
&:hover {
134+
background-color: #f0d500;
135+
transform: scale(1.075);
136+
}
137+
}
138+
}
97139
</style>

0 commit comments

Comments
 (0)