Fix errors on setups with no Notifications/SpeechSynthesis support
This commit is contained in:
		
							parent
							
								
									cb3bd4b881
								
							
						
					
					
						commit
						ca5d24385f
					
				
					 3 changed files with 33 additions and 22 deletions
				
			
		|  | @ -77,6 +77,8 @@ function _showNotification(notification: NotificationData, id: number) { | |||
| } | ||||
| 
 | ||||
| function shouldBeNative() { | ||||
|     if (typeof Notification === "undefined") return false; | ||||
| 
 | ||||
|     const { useNative } = Settings.notifications; | ||||
|     if (useNative === "always") return true; | ||||
|     if (useNative === "not-focused") return !document.hasFocus(); | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ | |||
| 
 | ||||
| 
 | ||||
| import { openNotificationLogModal } from "@api/Notifications/notificationLog"; | ||||
| import { useSettings } from "@api/settings"; | ||||
| import { Settings, useSettings } from "@api/settings"; | ||||
| import { classNameFactory } from "@api/Styles"; | ||||
| import DonateButton from "@components/DonateButton"; | ||||
| import ErrorBoundary from "@components/ErrorBoundary"; | ||||
|  | @ -43,7 +43,6 @@ function VencordSettings() { | |||
|         fallbackValue: "Loading..." | ||||
|     }); | ||||
|     const settings = useSettings(); | ||||
|     const notifSettings = settings.notifications; | ||||
| 
 | ||||
|     const donateImage = React.useMemo(() => Math.random() > 0.5 ? DEFAULT_DONATE_IMAGE : SHIGGY_DONATE_IMAGE, []); | ||||
| 
 | ||||
|  | @ -158,8 +157,16 @@ function VencordSettings() { | |||
|             </Forms.FormSection> | ||||
| 
 | ||||
| 
 | ||||
|             {typeof Notification !== "undefined" && <NotificationSection settings={settings.notifications} />} | ||||
|         </React.Fragment> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| function NotificationSection({ settings }: { settings: typeof Settings["notifications"]; }) { | ||||
|     return ( | ||||
|         <> | ||||
|             <Forms.FormTitle tag="h5">Notification Style</Forms.FormTitle> | ||||
|             {notifSettings.useNative !== "never" && Notification.permission === "denied" && ( | ||||
|             {settings.useNative !== "never" && Notification?.permission === "denied" && ( | ||||
|                 <ErrorCard style={{ padding: "1em" }} className={Margins.bottom8}> | ||||
|                     <Forms.FormTitle tag="h5">Desktop Notification Permission denied</Forms.FormTitle> | ||||
|                     <Forms.FormText>You have denied Notification Permissions. Thus, Desktop notifications will not work!</Forms.FormText> | ||||
|  | @ -178,35 +185,35 @@ function VencordSettings() { | |||
|                     { label: "Only use Desktop notifications when Discord is not focused", value: "not-focused", default: true }, | ||||
|                     { label: "Always use Desktop notifications", value: "always" }, | ||||
|                     { label: "Always use Vencord notifications", value: "never" }, | ||||
|                 ] satisfies Array<{ value: typeof settings["notifications"]["useNative"]; } & Record<string, any>>} | ||||
|                 ] satisfies Array<{ value: typeof settings["useNative"]; } & Record<string, any>>} | ||||
|                 closeOnSelect={true} | ||||
|                 select={v => notifSettings.useNative = v} | ||||
|                 isSelected={v => v === notifSettings.useNative} | ||||
|                 select={v => settings.useNative = v} | ||||
|                 isSelected={v => v === settings.useNative} | ||||
|                 serialize={identity} | ||||
|             /> | ||||
| 
 | ||||
|             <Forms.FormTitle tag="h5" className={Margins.top16 + " " + Margins.bottom8}>Notification Position</Forms.FormTitle> | ||||
|             <Select | ||||
|                 isDisabled={notifSettings.useNative === "always"} | ||||
|                 isDisabled={settings.useNative === "always"} | ||||
|                 placeholder="Notification Position" | ||||
|                 options={[ | ||||
|                     { label: "Bottom Right", value: "bottom-right", default: true }, | ||||
|                     { label: "Top Right", value: "top-right" }, | ||||
|                 ] satisfies Array<{ value: typeof settings["notifications"]["position"]; } & Record<string, any>>} | ||||
|                 select={v => notifSettings.position = v} | ||||
|                 isSelected={v => v === notifSettings.position} | ||||
|                 ] satisfies Array<{ value: typeof settings["position"]; } & Record<string, any>>} | ||||
|                 select={v => settings.position = v} | ||||
|                 isSelected={v => v === settings.position} | ||||
|                 serialize={identity} | ||||
|             /> | ||||
| 
 | ||||
|             <Forms.FormTitle tag="h5" className={Margins.top16 + " " + Margins.bottom8}>Notification Timeout</Forms.FormTitle> | ||||
|             <Forms.FormText className={Margins.bottom16}>Set to 0s to never automatically time out</Forms.FormText> | ||||
|             <Slider | ||||
|                 disabled={notifSettings.useNative === "always"} | ||||
|                 disabled={settings.useNative === "always"} | ||||
|                 markers={[0, 1000, 2500, 5000, 10_000, 20_000]} | ||||
|                 minValue={0} | ||||
|                 maxValue={20_000} | ||||
|                 initialValue={notifSettings.timeout} | ||||
|                 onValueChange={v => notifSettings.timeout = v} | ||||
|                 initialValue={settings.timeout} | ||||
|                 onValueChange={v => settings.timeout = v} | ||||
|                 onValueRender={v => (v / 1000).toFixed(2) + "s"} | ||||
|                 onMarkerRender={v => (v / 1000) + "s"} | ||||
|                 stickToMarkers={false} | ||||
|  | @ -222,23 +229,22 @@ function VencordSettings() { | |||
|                 minValue={0} | ||||
|                 maxValue={200} | ||||
|                 stickToMarkers={true} | ||||
|                 initialValue={notifSettings.logLimit} | ||||
|                 onValueChange={v => notifSettings.logLimit = v} | ||||
|                 initialValue={settings.logLimit} | ||||
|                 onValueChange={v => settings.logLimit = v} | ||||
|                 onValueRender={v => v === 200 ? "∞" : v} | ||||
|                 onMarkerRender={v => v === 200 ? "∞" : v} | ||||
|             /> | ||||
| 
 | ||||
|             <Button | ||||
|                 onClick={openNotificationLogModal} | ||||
|                 disabled={notifSettings.logLimit === 0} | ||||
|                 disabled={settings.logLimit === 0} | ||||
|             > | ||||
|                 Open Notification Log | ||||
|             </Button> | ||||
|         </React.Fragment> | ||||
|         </> | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| interface DonateCardProps { | ||||
|     image: string; | ||||
| } | ||||
|  |  | |||
|  | @ -192,10 +192,13 @@ export default definePlugin({ | |||
|     authors: [Devs.Ven], | ||||
| 
 | ||||
|     start() { | ||||
|         if (speechSynthesis.getVoices().length === 0) { | ||||
|             new Logger("VcNarrator").warn("No Narrator voices found. Thus, this plugin will not work. Check my Settings for more info"); | ||||
|         if (typeof speechSynthesis === "undefined" || speechSynthesis.getVoices().length === 0) { | ||||
|             new Logger("VcNarrator").warn( | ||||
|                 "SpeechSynthesis not supported or no Narrator voices found. Thus, this plugin will not work. Check my Settings for more info" | ||||
|             ); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         FluxDispatcher.subscribe("VOICE_STATE_UPDATES", handleVoiceStates); | ||||
|         FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_MUTE", handleToggleSelfMute); | ||||
|         FluxDispatcher.subscribe("AUDIO_TOGGLE_SELF_DEAF", handleToggleSelfDeafen); | ||||
|  | @ -214,11 +217,11 @@ export default definePlugin({ | |||
|             voice: { | ||||
|                 type: OptionType.SELECT, | ||||
|                 description: "Narrator Voice", | ||||
|                 options: speechSynthesis.getVoices().map(v => ({ | ||||
|                 options: speechSynthesis?.getVoices().map(v => ({ | ||||
|                     label: v.name, | ||||
|                     value: v.voiceURI, | ||||
|                     default: v.default | ||||
|                 })) | ||||
|                 })) ?? [] | ||||
|             }, | ||||
|             volume: { | ||||
|                 type: OptionType.SLIDER, | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue