Skip to content

Commit

Permalink
Add Producthunt extension (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
ragnorc authored Oct 17, 2021
1 parent d575da6 commit e2584f5
Show file tree
Hide file tree
Showing 7 changed files with 1,507 additions and 0 deletions.
10 changes: 10 additions & 0 deletions extensions/producthunt/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"root": true,
"env": {
"es2020": true,
"node": true
},
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "prettier"]
}
4 changes: 4 additions & 0 deletions extensions/producthunt/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"printWidth": 120,
"singleQuote": false
}
Binary file added extensions/producthunt/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions extensions/producthunt/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "producthunt",
"title": "Product Hunt - Today's Hunts",
"description": "Get the latest products from the fontpage of Product Hunt.",
"icon": "icon.png",
"author": "Ragnor Comerford",
"commands": [
{
"name": "frontpage",
"title": "Check Today's Hunts",
"subtitle": "Product Hunt",
"description": "Get the latest products from the fontpage of Product Hunt.",
"mode": "view"
}
],
"dependencies": {
"@raycast/api": "^1.25.0",
"got": "^11.8.2",
"rss-parser": "^3.12.0"
},
"devDependencies": {
"@types/node": "~16.10.0",
"@types/react": "^17.0.28",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"typescript": "^4.4.3"
},
"scripts": {
"build": "ray build -e dist",
"dev": "ray develop"
}
}
94 changes: 94 additions & 0 deletions extensions/producthunt/src/frontpage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { ActionPanel, CopyToClipboardAction, List, OpenInBrowserAction, showToast, ToastStyle } from "@raycast/api";
import { useEffect, useState } from "react";
import Parser from "rss-parser";

const parser = new Parser({
customFields: {
item: ["author"],
},
});

interface State {
items?: Parser.Item[];
error?: Error;
}

export default function Command() {
const [state, setState] = useState<State>({});

useEffect(() => {
async function fetchStories() {
try {
const feed = await parser.parseURL("https://www.producthunt.com/feed?category=undefined&count=25");
setState({ items: feed.items });
} catch (error) {
setState({ error: error instanceof Error ? error : new Error("Something went wrong") });
}
}

fetchStories();
}, []);

if (state.error) {
showToast(ToastStyle.Failure, "Failed loading stories", state.error.message);
}

return (
<List isLoading={!state.items && !state.error}>
{state.items?.map((item, index) => (
<StoryListItem key={item.guid} item={item} index={index} />
))}
</List>
);
}

function StoryListItem(props: { item: Parser.Item; index: number }) {
const icon = getIcon(props.index + 1);
console.log(props.item);
return (
<List.Item
icon={icon}
title={props.item.title ?? "No title"}
//@ts-ignore
subtitle={props.item.author ?? "No author"}
actions={<Actions item={props.item} />}
/>
);
}

function Actions(props: { item: Parser.Item }) {
return (
<ActionPanel title={props.item.title}>
<ActionPanel.Section>
{props.item.link && <OpenInBrowserAction url={props.item.link} />}
{props.item.guid && <OpenInBrowserAction url={props.item.guid} title="Open Comments in Browser" />}
</ActionPanel.Section>
<ActionPanel.Section>
{props.item.link && (
<CopyToClipboardAction
content={props.item.link}
title="Copy Link"
shortcut={{ modifiers: ["cmd"], key: "." }}
/>
)}
</ActionPanel.Section>
</ActionPanel>
);
}

const iconToEmojiMap = new Map<number, string>([
[1, "1️⃣"],
[2, "2️⃣"],
[3, "3️⃣"],
[4, "4️⃣"],
[5, "5️⃣"],
[6, "6️⃣"],
[7, "7️⃣"],
[8, "8️⃣"],
[9, "9️⃣"],
[10, "🔟"],
]);

function getIcon(index: number) {
return iconToEmojiMap.get(index) ?? "⏺";
}
16 changes: 16 additions & 0 deletions extensions/producthunt/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"display": "Node 16",
"include": ["src/**/*"],
"compilerOptions": {
"lib": ["es2020"],
"module": "commonjs",
"target": "es2020",
"strict": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"jsx": "react-jsx"
}
}
Loading

0 comments on commit e2584f5

Please sign in to comment.