From c1f2f820c17eb3673e0f7ae072cd76d86ec452ca Mon Sep 17 00:00:00 2001 From: Type <79042381+TypeFor@users.noreply.github.com> Date: Thu, 13 Aug 2026 11:43:32 +0200 Subject: [PATCH] CLN - remove weather camera views Remove the remote weather-camera experience from the phone UI, NUI test server, and weather state.\n\nDelete the associated client and server camera handlers, configuration, locale copy, and manifest entries while retaining the core weather forecast app. --- frontend/src/assets/main.css | 113 --------------------- frontend/src/stores/phone.ts | 22 ---- frontend/src/stores/weather.test.ts | 20 ---- frontend/src/stores/weather.ts | 40 +------- frontend/src/types/weather.ts | 5 - frontend/src/views/apps/WeatherApp.vue | 53 +--------- frontend/testserver/index.cjs | 22 ---- sky_phone/config/locales/en.lua | 12 --- sky_phone/config/weather_cameras.lua | 32 ------ sky_phone/fxmanifest.lua | 3 - sky_phone/source/client/weather_camera.lua | 103 ------------------- sky_phone/source/server/weather.lua | 62 ----------- 12 files changed, 2 insertions(+), 485 deletions(-) delete mode 100644 sky_phone/config/weather_cameras.lua delete mode 100644 sky_phone/source/client/weather_camera.lua delete mode 100644 sky_phone/source/server/weather.lua diff --git a/frontend/src/assets/main.css b/frontend/src/assets/main.css index f08c19d..8239d4b 100644 --- a/frontend/src/assets/main.css +++ b/frontend/src/assets/main.css @@ -3515,119 +3515,6 @@ button { letter-spacing: 0.04em; text-transform: uppercase; } -.weather-camera-card { - padding-bottom: 12px; -} -.weather-camera-preview { - position: relative; - min-height: 146px; - overflow: hidden; - background: - radial-gradient(circle at 75% 20%, #bfe8ff9c, transparent 28%), - linear-gradient(160deg, #82b4d5 0%, #496783 52%, #27364c 100%); -} -.weather-camera-preview--rain, -.weather-camera-preview--thunder { - background: - radial-gradient(circle at 70% 18%, #9cb4c380, transparent 26%), - linear-gradient(160deg, #667d8d 0%, #34495f 50%, #1a2839 100%); -} -.weather-camera-preview--clear, -.weather-camera-preview--sunny { - background: - radial-gradient(circle at 76% 19%, #fff4c9 0 5%, #ffd78370 6%, transparent 29%), - linear-gradient(160deg, #72b7df 0%, #4d86b2 55%, #35506e 100%); -} -.weather-camera-preview::after { - position: absolute; - inset: -50% 0 auto; - height: 3px; - background: #ffffff38; - box-shadow: 0 0 12px #fff8; - content: ''; - animation: weather-camera-scan 4s linear infinite; -} -.weather-camera-skyline { - position: absolute; - right: -5%; - bottom: 0; - left: -5%; - height: 51%; - background: - linear-gradient(90deg, transparent 0 5%, #142333 5% 17%, transparent 17% 21%, #192b3c 21% 34%, transparent 34% 42%, #11202f 42% 60%, transparent 60% 65%, #182a3b 65% 76%, transparent 76% 81%, #102131 81% 95%, transparent 95%), - linear-gradient(0deg, #111c2a 0 18%, transparent 18%); - clip-path: polygon(0 43%, 9% 43%, 9% 22%, 18% 22%, 18% 57%, 27% 57%, 27% 10%, 37% 10%, 37% 48%, 48% 48%, 48% 30%, 61% 30%, 61% 62%, 71% 62%, 71% 16%, 83% 16%, 83% 49%, 100% 49%, 100% 100%, 0 100%); - opacity: 0.85; -} -.weather-camera-meta, -.weather-camera-copy { - position: absolute; - z-index: 1; - right: 12px; - left: 12px; - display: flex; - justify-content: space-between; - text-shadow: 0 2px 8px #000c; -} -.weather-camera-meta { - top: 11px; - align-items: center; - font-size: 10px; - font-weight: 700; - text-transform: uppercase; -} -.weather-camera-live { - display: flex; - align-items: center; - gap: 5px; -} -.weather-camera-live i { - width: 7px; - height: 7px; - border-radius: 50%; - background: #ff4e5b; - box-shadow: 0 0 0 4px #ff4e5b2e; - animation: weather-camera-pulse 1.6s ease-in-out infinite; -} -.weather-camera-copy { - bottom: 10px; - align-items: flex-end; - flex-direction: column; -} -.weather-camera-copy strong { - font-size: 16px; -} -.weather-camera-copy span { - color: #ffffffc4; - font-size: 10px; -} -.weather-camera-action { - padding: 11px 12px 0; -} -.weather-camera-action button span { - display: flex; - align-items: center; - justify-content: center; - gap: 7px; -} -.weather-camera-action p { - margin: 8px 3px 0; - color: #ffd2d2; - font-size: 10px; - text-align: center; -} -.weather-camera-unavailable { - padding: 16px; - color: #ffffffb3; - font-size: 12px; - text-align: center; -} -@keyframes weather-camera-scan { - to { transform: translateY(290px); } -} -@keyframes weather-camera-pulse { - 50% { opacity: 0.45; } -} .weather-hourly { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); diff --git a/frontend/src/stores/phone.ts b/frontend/src/stores/phone.ts index 7ab4eae..e9288b9 100644 --- a/frontend/src/stores/phone.ts +++ b/frontend/src/stores/phone.ts @@ -2338,28 +2338,6 @@ const defaultLocales: LocaleTree = { unavailable: 'Weather is unavailable', stale: 'Showing the last available weather update.', tryAgain: 'Try Again', - webcam: { - title: 'Weather Cameras', - live: 'LIVE', - view: 'View Live Camera', - subtitle: 'A live look at current conditions', - unavailable: 'No weather cameras are available.', - locations: { - legion_square: 'Legion Square', - sandy_shores: 'Sandy Shores', - cayo_airstrip: 'Cayo Perico Airstrip', - }, - errors: { - camera_disabled: 'Weather cameras are currently disabled.', - camera_not_found: 'This weather camera is no longer available.', - camera_requires_safe_position: - 'Stand still and exit your vehicle before opening a camera.', - camera_active: 'A weather camera is already open.', - rate_limited: 'Too many camera requests. Try again shortly.', - request_failed: 'The weather camera could not be opened.', - not_authenticated: 'Unlock the phone before opening a camera.', - }, - }, regions: { los_santos: 'Los Santos', blaine_county: 'Blaine County', diff --git a/frontend/src/stores/weather.test.ts b/frontend/src/stores/weather.test.ts index b89b26a..53e3526 100644 --- a/frontend/src/stores/weather.test.ts +++ b/frontend/src/stores/weather.test.ts @@ -61,24 +61,4 @@ describe('weather store', () => { expect(weather.error).toBe('offline') }) - it('loads the server-approved camera list and opens a camera by id', async () => { - vi.mocked(nuiCall) - .mockResolvedValueOnce({ - data: { cameras: [{ id: 'legion_square', region: 'los_santos' }] }, - success: true, - }) - .mockResolvedValueOnce({ success: true }) - const weather = useWeatherStore() - - await weather.loadCameras() - const opened = await weather.openCamera('legion_square') - - expect(weather.cameras).toEqual([ - { id: 'legion_square', region: 'los_santos' }, - ]) - expect(nuiCall).toHaveBeenLastCalledWith('weather:camera-open', { - id: 'legion_square', - }) - expect(opened).toBe(true) - }) }) diff --git a/frontend/src/stores/weather.ts b/frontend/src/stores/weather.ts index e94dbe6..103c378 100644 --- a/frontend/src/stores/weather.ts +++ b/frontend/src/stores/weather.ts @@ -1,10 +1,6 @@ import { defineStore } from 'pinia' -import type { - RawWeatherSnapshot, - WeatherCamera, - WeatherForecast, -} from '@/types/weather' +import type { RawWeatherSnapshot, WeatherForecast } from '@/types/weather' import { nuiCall } from '@/utils/nui' import { buildWeatherForecast } from '@/utils/weather' @@ -13,45 +9,12 @@ const REFRESH_INTERVAL = 30_000 export const useWeatherStore = defineStore('weather', { state: () => ({ error: null as string | null, - cameraError: null as string | null, - cameras: [] as WeatherCamera[], - camerasLoaded: false, forecast: null as WeatherForecast | null, intervalId: undefined as number | undefined, isLoading: false, - isOpeningCamera: false, lastFetchedAt: 0, }), actions: { - async loadCameras(force = false): Promise { - if (this.camerasLoaded && !force) return - const response = await nuiCall<{ cameras: WeatherCamera[] }>( - 'weather:cameras', - ) - this.camerasLoaded = true - if (!response.success || !Array.isArray(response.data?.cameras)) { - this.cameraError = response.error ?? 'request_failed' - return - } - this.cameras = response.data.cameras.filter( - (camera) => - typeof camera?.id === 'string' && - ['los_santos', 'blaine_county', 'cayo_perico'].includes( - camera.region, - ), - ) - this.cameraError = null - }, - async openCamera(id: string): Promise { - if (this.isOpeningCamera) return false - this.isOpeningCamera = true - const response = await nuiCall('weather:camera-open', { id }) - this.isOpeningCamera = false - this.cameraError = response.success - ? null - : (response.error ?? 'request_failed') - return response.success - }, async refresh(force = false): Promise { if (this.isLoading) return if (!force && Date.now() - this.lastFetchedAt < REFRESH_INTERVAL) return @@ -68,7 +31,6 @@ export const useWeatherStore = defineStore('weather', { }, start(): void { void this.refresh(true) - void this.loadCameras() if (this.intervalId !== undefined) return this.intervalId = window.setInterval(() => void this.refresh(true), REFRESH_INTERVAL) }, diff --git a/frontend/src/types/weather.ts b/frontend/src/types/weather.ts index 568ac93..14918a5 100644 --- a/frontend/src/types/weather.ts +++ b/frontend/src/types/weather.ts @@ -10,11 +10,6 @@ export type WeatherConditionId = export type WeatherRegionId = 'los_santos' | 'blaine_county' | 'cayo_perico' -export type WeatherCamera = { - id: string - region: WeatherRegionId -} - export type WeatherClock = { day: number hour: number diff --git a/frontend/src/views/apps/WeatherApp.vue b/frontend/src/views/apps/WeatherApp.vue index af217fd..9a3569b 100644 --- a/frontend/src/views/apps/WeatherApp.vue +++ b/frontend/src/views/apps/WeatherApp.vue @@ -1,5 +1,5 @@