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