Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ apiKey: <your twickets api key> # REQUIRED: See README.md for details on how to

country: GB # Currently only GB is supported

flaresolverrUrl: <your flaresolverr url> # Optional: URL of FlareSolverr proxy server for bypassing Cloudflare (Required restart)

# Notification service configuration
# Remove/comment out services you don't need
notification:
Expand Down
13 changes: 10 additions & 3 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ tasks:
- pnpm run lint

generate:
- task: build:be
- task: build:fe
aliases:
- gen
cmds:
- task: generate:be
- task: generate:fe

generate:be:
aliases:
Expand Down Expand Up @@ -65,7 +68,7 @@ tasks:
build:fe:
dir: frontend
cmds:
- run build
- pnpm run build

run:be:
cmds:
Expand All @@ -83,3 +86,7 @@ tasks:
docker:run:
cmds:
- docker compose up --build

docker:run:services:
cmds:
- docker compose up flaresolverr -d
11 changes: 11 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,14 @@ services:
- 9000:9000
volumes:
- ./config.yaml:/twitchets/config.yaml

flaresolverr:
container_name: flaresolverr
image: ghcr.io/flaresolverr/flaresolverr:latest
restart: unless-stopped
ports:
- 8191:8191
environment:
- LOG_LEVEL=info
- LOG_HTML=true
- TZ=Europe/London
2 changes: 2 additions & 0 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ apiKey: <your twickets api key> # REQUIRED: See README.md for details on how to

country: GB # Currently only GB is supported

flaresolverrUrl: <your flaresolverr url> # Optional: URL of FlareSolverr proxy server for bypassing Cloudflare (Required restart)

# Notification service configuration
# Remove/comment out services you don't need
notification:
Expand Down
70 changes: 37 additions & 33 deletions config/config.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions frontend/src/components/configField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface ConfigFieldProps<T extends string | number> {
description: string;
type: "text" | "number" | "integer" | "fraction" | "percentage" | "price";
value?: T;
placeholder?: string; // Can be overridden by default or global value placeholder
showReset?: boolean; // Whether to show reset button
resetValue?: T; // Value to set when reset is clicked
defaultValuePlaceholder?: string; // Placeholder to use when field will use the default value (i.e. reset)
Expand All @@ -22,6 +23,7 @@ export function ConfigField<T extends string | number>({
description,
type,
value,
placeholder,
resetValue,
globalValuePlaceholder,
defaultValuePlaceholder,
Expand All @@ -30,21 +32,21 @@ export function ConfigField<T extends string | number>({
updateValue,
}: ConfigFieldProps<T>) {
let fieldValue = value;
let fieldPlaceholder = placeholder;

// Determine whether value means field will use global/default
// value, and there the placeholder to use.
let isLinkedToGlobal = false;
let placeholder = "";
if (showGlobalReset && fieldValue === undefined) {
placeholder = `${globalValuePlaceholder} (Global)`;
fieldPlaceholder = `${globalValuePlaceholder} (Global)`;
isLinkedToGlobal = true;
} else if (
showReset &&
(fieldValue === undefined ||
(typeof fieldValue === "string" && fieldValue === "") ||
(typeof fieldValue === "number" && fieldValue < 0))
) {
placeholder = `${defaultValuePlaceholder} (Default)`;
fieldPlaceholder = `${defaultValuePlaceholder} (Default)`;
fieldValue = undefined; // Unset value so placeholder is shown
}

Expand All @@ -54,7 +56,7 @@ export function ConfigField<T extends string | number>({
<Input
type="text"
value={fieldValue ?? ""}
placeholder={placeholder}
placeholder={fieldPlaceholder}
onChange={(event) => updateValue(event.target.value as T)}
/>
);
Expand All @@ -65,7 +67,7 @@ export function ConfigField<T extends string | number>({
<NumericFormat
customInput={Input}
value={fieldValue ?? ""}
placeholder={placeholder}
placeholder={fieldPlaceholder}
allowNegative={false}
decimalScale={type === "integer" ? 0 : undefined}
onValueChange={(values) => {
Expand Down
24 changes: 22 additions & 2 deletions frontend/src/components/configGeneral.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useConfig } from "../providers/config";
import type { Country } from "../types/config";
import { SaveDiscardButtons } from "./buttonsSaveDiscard";
import { CollapsibleCard } from "./cardCollapsible";
import { ConfigField } from "./configField";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Label } from "./ui/label";
Expand All @@ -24,17 +25,23 @@ export function GeneralSettings() {
const [draft, setDraft] = useState({
apiKey: config.apiKey,
country: config.country,
flaresolverrUrl: config.flaresolverrUrl,
});
const [showApiKey, setShowApiKey] = useState(false);

// If the canonical config changes, reset the draft
useEffect(() => {
setDraft({ apiKey: config.apiKey, country: config.country });
}, [config.apiKey, config.country]);
setDraft({
apiKey: config.apiKey,
country: config.country,
flaresolverrUrl: config.flaresolverrUrl,
});
}, [config.apiKey, config.country, config.flaresolverrUrl]);

const hasChanges = !isEqual(draft, {
apiKey: config.apiKey,
country: config.country,
flaresolverrUrl: config.flaresolverrUrl,
});

const toggleShowApiKey = () => {
Expand All @@ -51,12 +58,14 @@ export function GeneralSettings() {
onSave={() => {
updateConfig((config) => {
config.apiKey = draft.apiKey;
config.flaresolverrUrl = draft.flaresolverrUrl;
config.country = draft.country;
});
}}
onDiscard={() => {
setDraft({
apiKey: config.apiKey,
flaresolverrUrl: config.flaresolverrUrl,
country: config.country,
});
}}
Expand Down Expand Up @@ -113,6 +122,17 @@ export function GeneralSettings() {
</SelectContent>
</Select>
</div>

<ConfigField
label="FlareSolverr URL"
description="Optional: URL of FlareSolverr proxy server for bypassing Cloudflare (requires restart)"
type="text"
value={draft.flaresolverrUrl}
showReset={false}
updateValue={(value) => {
setDraft((prev) => ({ ...prev, flaresolverrUrl: value }));
}}
/>
</div>
</CollapsibleCard>
);
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/types/openapi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ export interface components {
url: string;
/** @description If using https://ntfy.sh, make sure this is unique to you! */
topic: string;
/** @description Optional: for authenticated instances */
username: string;
/** @description Optional: for authenticated instances */
password: string;
/** @description Username for authenticated instances (Optional) */
username?: string;
/** @description Password for authenticated instances (Optional) */
password?: string;
};
GotifyConfig: {
/** @description Your Gotify server URL */
Expand Down Expand Up @@ -239,6 +239,8 @@ export interface components {
/** @description REQUIRED: See README.md for details on how to obtain */
apiKey: string;
country: components["schemas"]["Country"];
/** @description URL of FlareSolverr proxy server for bypassing Cloudflare (Optional) */
flaresolverrUrl?: string;
notification: components["schemas"]["NotificationConfig"];
global: components["schemas"]["GlobalTicketListingConfig"];
tickets: components["schemas"]["TicketListingConfig"][];
Expand Down
Loading