From 90e783b82138fea9ca8b948e2a45f4aa25a6e58e Mon Sep 17 00:00:00 2001 From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com> Date: Sun, 30 Nov 2025 18:25:32 +0100 Subject: [PATCH] "slightly" jolly the client --- .github/workflows/release.yml | 64 ++-- scripts/build.mjs | 2 +- src/core/i18n/default.json | 4 +- src/core/plugins/index.ts | 1 + src/core/plugins/shiggyenhancements/index.tsx | 287 +++++++++++++++++- src/core/ui/settings/pages/General/About.tsx | 2 +- src/core/ui/settings/pages/General/index.tsx | 2 +- 7 files changed, 329 insertions(+), 33 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8023de5..14a6768 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,6 +5,15 @@ on: branches: - main workflow_dispatch: + inputs: + release_name: + description: 'Custom Release Name (e.g., "Jolly", "Christmas")' + required: true + type: string + release_tag: + description: 'Release Tag (e.g., "v1.0.0")' + required: true + type: string jobs: release: @@ -29,33 +38,38 @@ jobs: run: bun install shell: bash - - name: Extract version - id: extract + - name: Determine Release Info + id: release_info run: | - # Extract major.minor.patch version from scripts/build.mjs - # This locates the first quoted three-segment version string in the build script (e.g. "1.1.7") - if [ ! -f scripts/build.mjs ]; then - echo "scripts/build.mjs not found" >&2 - exit 1 - fi - # Print a snippet of the file for debugging in workflow logs - echo '--- scripts/build.mjs (snippet) ---' >&2 - sed -n '1,200p' scripts/build.mjs >&2 || true + # For workflow_dispatch, use the provided inputs + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + release_name="${{ github.event.inputs.release_name }}" + release_tag="${{ github.event.inputs.release_tag }}" + else + # For push events, extract version and generate a name + if [ ! -f scripts/build.mjs ]; then + echo "scripts/build.mjs not found" >&2 + exit 1 + fi - # Primary extraction: find the first quoted semver (may include prerelease suffix, but we strip it) - raw=$(grep -m1 -oE '\"[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?\"' scripts/build.mjs | tr -d '\"' | head -n1 || true) + # Extract version + raw=$(grep -m1 -oE '\"[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?\"' scripts/build.mjs | tr -d '\"' | head -n1 || true) + version=$(printf '%s' "$raw" | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/') - # Strip any prerelease suffix, keep only major.minor.patch - version=$(printf '%s' "$raw" | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+).*/\1/') + if ! printf '%s' "$version" | grep -xE '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then + echo "Failed to extract a valid base version from scripts/build.mjs" >&2 + exit 1 + fi - # Validate final result is exactly major.minor.patch - if ! printf '%s' "$version" | grep -xE '^[0-9]+\.[0-9]+\.[0-9]+$' >/dev/null; then - echo "Failed to extract a valid base version from scripts/build.mjs" >&2 - sed -n '1,200p' scripts/build.mjs >&2 || true - exit 1 + # Use version-based naming for push events + release_name="Release v${version}" + release_tag="v${version}" fi - echo "version=$version" >> $GITHUB_OUTPUT + echo "release_name=${release_name}" >> $GITHUB_OUTPUT + echo "release_tag=${release_tag}" >> $GITHUB_OUTPUT + echo "Using release name: ${release_name}" >&2 + echo "Using release tag: ${release_tag}" >&2 shell: bash - name: Prepare tag @@ -65,9 +79,7 @@ jobs: run: | set -euo pipefail - # Use the extracted version directly as the tag for main branch releases - version="${{ steps.extract.outputs.version }}" - tag="${version}" + tag="${{ steps.release_info.outputs.release_tag }}" echo "[debug] computed tag=${tag}" >&2 @@ -95,8 +107,8 @@ jobs: - name: Create Release uses: softprops/action-gh-release@v1 with: - tag_name: ${{ steps.prepare.outputs.tag }} - name: Release ${{ steps.prepare.outputs.tag }} + tag_name: ${{ steps.release_info.outputs.release_tag }} + name: ${{ steps.release_info.outputs.release_name }} files: | dist/shiggycord.js dist/shiggycord.min.js diff --git a/scripts/build.mjs b/scripts/build.mjs index 773c511..7c18828 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -74,7 +74,7 @@ const config = { constModules: { globals: { "bunny-build-info": { - version: `"1.1.11"`, + version: `"Jolly"`, }, }, }, diff --git a/src/core/i18n/default.json b/src/core/i18n/default.json index 054f556..e083130 100644 --- a/src/core/i18n/default.json +++ b/src/core/i18n/default.json @@ -6,8 +6,8 @@ "ARE_YOU_SURE_TO_DELETE_THEME": "Are you sure you wish to delete {name}?", "ASSET_BROWSER": "Asset Browser", "BRAND": "Brand", - "SHIGGYCORD": "ShiggyCord", - "SHIGGYCORD_URL": "ShiggyCord URL", + "SHIGGYCORD": "ShiggyCold", + "SHIGGYCORD_URL": "ShiggyCold URL", "BROWSER": "Browser", "BYTECODE": "Bytecode", "CANCEL": "Cancel", diff --git a/src/core/plugins/index.ts b/src/core/plugins/index.ts index 3f2c292..9dacb44 100644 --- a/src/core/plugins/index.ts +++ b/src/core/plugins/index.ts @@ -12,6 +12,7 @@ export const getCorePlugins = (): Record => ({ "bunny.notrack": require("./notrack"), "bunny.messagefix": require("./messagefix"), "bunny.fixembed": require("./fixembed"), + "bunny.enhancements": require("./shiggyenhancements") }); /** diff --git a/src/core/plugins/shiggyenhancements/index.tsx b/src/core/plugins/shiggyenhancements/index.tsx index fd24cd1..441db09 100644 --- a/src/core/plugins/shiggyenhancements/index.tsx +++ b/src/core/plugins/shiggyenhancements/index.tsx @@ -1,4 +1,103 @@ import { defineCorePlugin } from ".."; +import { findByProps } from "@metro"; +import { logger } from "@lib/utils/logger"; +import { settings } from "@lib/api/settings"; +import { React } from "@metro/common"; + +const { TableRowGroup, TableRow, TableSwitchRow, Stack } = findByProps( + "TableRowGroup", + "TableRow", + "TableSwitchRow", + "Stack", +); +const { ScrollView } = require("react-native"); + +// Get ReactNative for NativeModules +const { ReactNative } = window as any; +const { DCDSoundManager } = ReactNative?.NativeModules || {}; + +// Sound settings type +type SoundSettings = { + enabled: boolean; + probability: number; +}; + +declare module "@lib/api/settings" { + interface Settings { + startupSound?: SoundSettings; + } +} + +const soundUrl = + "https://github.com/kmmiio99o/kmmiio99o.github.io/raw/refs/heads/main/music/shiggycord.mp3"; +const soundId = 6971; +let soundDuration = -1; +let timeoutId: NodeJS.Timeout | null = null; +let isPlaying = false; +let isPrepared = false; + +// Function to prepare the sound +const prepareSound = function (): Promise { + return new Promise(function (resolve) { + if (!DCDSoundManager) { + logger.error("DCDSoundManager not available"); + resolve(null); + return; + } + + DCDSoundManager.prepare( + soundUrl, + "music", + soundId, + function (error: any, sound: any) { + if (error) { + logger.error("Failed to prepare sound:", error); + resolve(null); + } else { + resolve(sound); + } + }, + ); + }); +}; + +// Function to play the sound +async function playSound() { + if (!DCDSoundManager) { + logger.error("DCDSoundManager not available for playback"); + return; + } + + if (isPlaying) { + if (timeoutId != null) clearTimeout(timeoutId); + DCDSoundManager.stop(soundId); + isPlaying = false; + } + + isPlaying = true; + + try { + await DCDSoundManager.play(soundId); + + if (soundDuration > 0) { + timeoutId = setTimeout(function () { + isPlaying = false; + DCDSoundManager.stop(soundId); + timeoutId = null; + }, soundDuration); + } + } catch (error) { + logger.error("Error playing sound:", error); + isPlaying = false; + } +} + +// Check if we should play based on probability +function shouldPlaySound(): boolean { + const probability = settings.startupSound?.probability ?? 2; + const random = Math.random() * 100; + return random <= probability; +} export default defineCorePlugin({ manifest: { @@ -10,9 +109,193 @@ export default defineCorePlugin({ display: { name: "Shiggy Enhancements", description: - "Fixes common discord bugs because discord wont (originally Kettu Enhancements)", + "Fixes common discord bugs because discord wont, and adds some features. (Originally Kettu Enhancements)", authors: [{ name: "cocobo1" }, { name: "Shiggy Team" }], }, }, - start() {}, + + SettingsComponent() { + const { useState, useEffect } = React; + const [config, setConfig] = useState({ + enabled: settings.startupSound?.enabled ?? true, + probability: settings.startupSound?.probability ?? 2, + }); + + useEffect(() => { + settings.startupSound = config; + }, [config]); + + const updateConfig = ( + key: keyof SoundSettings, + value: boolean | number, + ) => { + setConfig((prev) => ({ ...prev, [key]: value })); + }; + + // Get UI components including TextInput + const { + TableRowGroup: _TRG, + TableRow: _TR, + TableSwitchRow: _TSR, + Stack: _S, + TextInput: _TextInput, + } = findByProps( + "TableRowGroup", + "TableRow", + "TableSwitchRow", + "Stack", + "TextInput", + ); + + // Fallback if table components aren't available + if (!_TRG || !_TSR || !_TR || !_S) { + const FallbackText = + "Startup Sound UI unavailable (missing TableRow components)."; + return React.createElement( + ScrollView, + { style: { flex: 1, padding: 12 } }, + FallbackText, + ); + } + + const TableRowGroup = _TRG; + const TableRow = _TR; + const TableSwitchRow = _TSR; + const Stack = _S; + const TextInput = _TextInput; + + // Handle probability input change + const handleProbabilityChange = (v: string) => { + const num = parseInt(v); + if (!isNaN(num) && num >= 0 && num <= 100) { + updateConfig("probability", num); + } else if (v === "") { + updateConfig("probability", 0); + } + }; + + // Create settings elements + const settingsElements = []; + + // Startup Sound toggle with probability display + settingsElements.push( + React.createElement( + TableRowGroup, + { title: "Startup Sound", key: "startup-sound" }, + React.createElement(TableSwitchRow, { + label: "Enable Startup Sound", + value: config.enabled, + onValueChange: (v: boolean) => updateConfig("enabled", v), + }), + React.createElement(TableRow, { + label: "Play Chance", + subLabel: `Current: ${config.probability}% chance to play on startup`, + }), + ), + ); + + // Probability input in its own invisible group + if (TextInput) { + settingsElements.push( + React.createElement( + TableRowGroup, + { title: "", key: "probability-input-group" }, + React.createElement(TextInput, { + placeholder: "Enter probability (0-100)", + value: config.probability.toString(), + onChange: handleProbabilityChange, + key: "probability-input", + }), + ), + ); + } + + // About section + settingsElements.push( + React.createElement( + TableRowGroup, + { title: "About", key: "about" }, + React.createElement(TableRow, { + label: "Description", + subLabel: + "Shiggy Enhancements, more options, more features. Originally Kettu Enhancements with additinal features.", + disabled: true, + }), + ), + ); + + return React.createElement( + ScrollView, + { style: { flex: 1 } }, + React.createElement( + Stack, + { spacing: 8, style: { padding: 10 } }, + ...settingsElements, + ), + ); + }, + + start() { + logger.log("Shiggy Enhancements: Starting plugin"); + + // Initialize sound settings + settings.startupSound = settings.startupSound || { + enabled: true, + probability: 2, + }; + + // Check if DCDSoundManager is available + if (!DCDSoundManager) { + logger.error("DCDSoundManager not found - startup sound disabled"); + return; + } + + // Play startup sound if enabled and probability check passes + if (settings.startupSound.enabled && shouldPlaySound()) { + logger.log( + `Attempting to play startup sound (${settings.startupSound.probability}% chance)`, + ); + + // Always prepare the sound fresh each time + prepareSound() + .then(function (sound) { + if (sound) { + isPrepared = true; + soundDuration = sound.duration || 5000; + logger.log(`Sound prepared, duration: ${soundDuration}ms`); + playSound(); + logger.log( + `Startup sound played (${settings.startupSound?.probability}% chance)`, + ); + } else { + logger.error("Failed to prepare sound"); + } + }) + .catch((error) => { + logger.error("Error in sound preparation:", error); + }); + } else if (settings.startupSound.enabled) { + logger.log( + `Startup sound skipped due to probability (${settings.startupSound?.probability}% chance)`, + ); + } + }, + + stop() { + logger.log("Shiggy Enhancements: Stopping plugin"); + + // Stop and cleanup audio + if (DCDSoundManager && isPlaying) { + DCDSoundManager.stop(soundId); + isPlaying = false; + } + + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + + // Reset preparation state so it can play again next time + isPrepared = false; + }, }); diff --git a/src/core/ui/settings/pages/General/About.tsx b/src/core/ui/settings/pages/General/About.tsx index 9bdf8da..98be97b 100644 --- a/src/core/ui/settings/pages/General/About.tsx +++ b/src/core/ui/settings/pages/General/About.tsx @@ -93,7 +93,7 @@ export default function About() { variant="text-md/medium" style={{ textAlign: "center", marginTop: 4 }} > - Shiggy your discord client! + Jolly your discord client! diff --git a/src/core/ui/settings/pages/General/index.tsx b/src/core/ui/settings/pages/General/index.tsx index 1378c6f..976f1ce 100644 --- a/src/core/ui/settings/pages/General/index.tsx +++ b/src/core/ui/settings/pages/General/index.tsx @@ -40,7 +40,7 @@ export default function General() { > } trailing={} />