diff --git a/firestore.rules b/firestore.rules index b6375fc857..d513802e84 100644 --- a/firestore.rules +++ b/firestore.rules @@ -18,7 +18,7 @@ service cloud.firestore { allow write: if request.auth.uid != null; } match /users/{userId} { - allow read: if true; + allow read: if request.auth.uid != null; allow write: if request.auth.uid == userId; match /visits/{venueId} { diff --git a/package-lock.json b/package-lock.json index 05ac6dee29..2751d358b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3122,11 +3122,18 @@ } }, "@fortawesome/free-solid-svg-icons": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.1.tgz", - "integrity": "sha512-EFMuKtzRMNbvjab/SvJBaOOpaqJfdSap/Nl6hst7CgrJxwfORR1drdTV6q1Ib/JVzq4xObdTDcT6sqTaXMqfdg==", + "version": "5.15.3", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz", + "integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.32" + "@fortawesome/fontawesome-common-types": "^0.2.35" + }, + "dependencies": { + "@fortawesome/fontawesome-common-types": { + "version": "0.2.35", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz", + "integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==" + } } }, "@fortawesome/react-fontawesome": { @@ -5895,9 +5902,9 @@ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==" }, "@types/qs": { - "version": "6.9.3", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.3.tgz", - "integrity": "sha512-7s9EQWupR1fTc2pSMtXRQ9w9gLOcrJn+h7HOXw4evxyvVqMi4f+q7d2tnFe3ng3SNHjtK+0EzGMGFUQX4/AQRA==" + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/react": { "version": "16.9.35", @@ -23970,9 +23977,9 @@ "integrity": "sha512-G7gRqKbi9NE025XVyqyTV98dxUOtdKvu/P1QRaVZfA55aEcXgjbxPdm+TlWdcSMNPKijlaHNz61DGPyelouRlA==" }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" } } }, diff --git a/package.json b/package.json index dba323c341..f33a0df633 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.32", "@fortawesome/free-brands-svg-icons": "^5.15.1", "@fortawesome/free-regular-svg-icons": "^5.15.1", - "@fortawesome/free-solid-svg-icons": "^5.15.1", + "@fortawesome/free-solid-svg-icons": "^5.15.3", "@fortawesome/react-fontawesome": "^0.1.13", "@reduxjs/toolkit": "^1.6.0", "@testing-library/jest-dom": "^4.2.4", @@ -16,7 +16,7 @@ "@testing-library/user-event": "^7.2.1", "@types/mixpanel-browser": "^2.35.4", "@types/mousetrap": "^1.6.4", - "@types/qs": "^6.9.3", + "@types/qs": "^6.9.7", "@types/react-resize-detector": "^4.2.0", "@types/styled-components": "^5.1.4", "@types/ws": "^7.2.6", diff --git a/public/index.html b/public/index.html index a2f1dbfd96..2d67b1b1dc 100644 --- a/public/index.html +++ b/public/index.html @@ -75,6 +75,6 @@ -
+
Loading...
diff --git a/reporting/package-lock.json b/reporting/package-lock.json index 67fbe01206..fbd3fb1c1d 100644 --- a/reporting/package-lock.json +++ b/reporting/package-lock.json @@ -9,9 +9,9 @@ "integrity": "sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg==" }, "@types/puppeteer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz", - "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==", + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.4.tgz", + "integrity": "sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==", "dev": true, "requires": { "@types/node": "*" diff --git a/reporting/package.json b/reporting/package.json index 2b5691f329..382796e146 100644 --- a/reporting/package.json +++ b/reporting/package.json @@ -11,6 +11,6 @@ }, "private": true, "devDependencies": { - "@types/puppeteer": "^5.4.3" + "@types/puppeteer": "^5.4.4" } } diff --git a/src/api/admin.ts b/src/api/admin.ts index eb3eedd156..33f8615460 100644 --- a/src/api/admin.ts +++ b/src/api/admin.ts @@ -41,13 +41,11 @@ export interface AdvancedVenueInput { type VenueImageFileKeys = | "bannerImageFile" | "logoImageFile" - | "mapIconImageFile" | "mapBackgroundImageFile"; type VenueImageUrlKeys = | "bannerImageUrl" | "logoImageUrl" - | "mapIconImageUrl" | "mapBackgroundImageUrl"; type ImageFileKeys = @@ -80,7 +78,6 @@ export type VenueInput = AdvancedVenueInput & name: string; bannerImageFile?: FileList; logoImageFile?: FileList; - mapIconImageFile?: FileList; mapBackgroundImageFile?: FileList; subtitle: string; description: string; @@ -145,8 +142,6 @@ type FirestoreRoomInput_v2 = Omit & }; export type PlacementInput = { - mapIconImageFile?: FileList; - mapIconImageUrl?: string; addressText?: string; notes?: string; placement?: Omit; @@ -185,10 +180,6 @@ const createFirestoreVenueInput = async (input: VenueInput, user: UserInfo) => { fileKey: "bannerImageFile", urlKey: "bannerImageUrl", }, - { - fileKey: "mapIconImageFile", - urlKey: "mapIconImageUrl", - }, { fileKey: "mapBackgroundImageFile", urlKey: "mapBackgroundImageUrl", diff --git a/src/components/atoms/UserAvatar/UserAvatar.scss b/src/components/atoms/UserAvatar/UserAvatar.scss index 4a56415677..4cd4331caf 100644 --- a/src/components/atoms/UserAvatar/UserAvatar.scss +++ b/src/components/atoms/UserAvatar/UserAvatar.scss @@ -1,9 +1,26 @@ @import "scss/constants"; .UserAvatar { + $avatar-sizes-map: ( + small: 25px, + medium: 40px, + large: 54px, + full: 100%, + ); + $indicator-sizes-map: ( + small: 8px, + medium: 10px, + large: 12px, + full: 25%, + ); + + // NOTE: parent and img mismatch due to legacy reasons + $default-avatar-size: 25px; + $default-image-size: 100%; + $default-indicator-size: 8px; + + @include square-size($default-avatar-size); position: relative; - width: 25px; - height: 25px; &:hover { .UserAvatar__nametag--hover { @@ -19,25 +36,24 @@ } &__image { - height: 100%; - width: 100%; + @include square-size($default-image-size); border-radius: 50%; vertical-align: unset; } &__status-indicator { position: absolute; - bottom: -1px; - right: -1px; + bottom: 0; + right: 0; border-radius: 50%; - height: 8px; - width: 8px; z-index: z(user-avatar-status-indicator); display: block; + @include square-size($default-indicator-size); - &--large { - height: 12px; - width: 12px; + @each $modifier, $size in $indicator-sizes-map { + &--#{$modifier} { + @include square-size($size); + } } } @@ -49,19 +65,11 @@ } } - &--small { - width: 25px; - height: 25px; - } - - &--medium { - height: 40px; - width: 40px; - } - - &--large { - height: 54px; - width: 54px; + @each $modifier, $size in $avatar-sizes-map { + &--#{$modifier}, + &--#{$modifier} img { + @include square-size($size); + } } &__nametag { @@ -74,12 +82,11 @@ text-align: center; - margin: 0 auto; + margin: 0 -50% 0 auto; padding: 0 $spacing--xs; bottom: 10%; left: 50%; - margin-right: -50%; border-radius: $border-radius--md; diff --git a/src/components/atoms/UserAvatar/UserAvatar.tsx b/src/components/atoms/UserAvatar/UserAvatar.tsx index b32bcaa080..48630adb12 100644 --- a/src/components/atoms/UserAvatar/UserAvatar.tsx +++ b/src/components/atoms/UserAvatar/UserAvatar.tsx @@ -14,6 +14,8 @@ import { useVenueId } from "hooks/useVenueId"; import "./UserAvatar.scss"; +export type UserAvatarSize = "small" | "medium" | "large" | "full"; + export interface UserAvatarProps { user?: WithId; containerClassName?: string; @@ -21,8 +23,7 @@ export interface UserAvatarProps { showNametag?: UsernameVisibility; showStatus?: boolean; onClick?: () => void; - large?: boolean; - medium?: boolean; + size?: UserAvatarSize; } // @debt the UserProfilePicture component serves a very similar purpose to this, we should unify them as much as possible @@ -33,8 +34,7 @@ export const _UserAvatar: React.FC = ({ showNametag, onClick, showStatus, - large, - medium, + size, }) => { const venueId = useVenueId(); @@ -56,8 +56,7 @@ export const _UserAvatar: React.FC = ({ const containerClasses = classNames("UserAvatar", containerClassName, { "UserAvatar--clickable": onClick !== undefined, - "UserAvatar--large": large, - "UserAvatar--medium": medium, + [`UserAvatar--${size}`]: size, }); const isOnline = useMemo( @@ -76,7 +75,7 @@ export const _UserAvatar: React.FC = ({ const statusIndicatorClasses = classNames("UserAvatar__status-indicator", { "UserAvatar__status-indicator--online": isOnline, [`UserAvatar__status-indicator--${status}`]: isOnline && status, - "UserAvatar__status-indicator--large": large, + [`UserAvatar__status-indicator--${size}`]: size, }); const statusIndicatorStyles = useMemo( diff --git a/src/components/molecules/ChatMessageBox/ChatMessageBox.scss b/src/components/molecules/ChatMessageBox/ChatMessageBox.scss index 446dbc47af..6a02ec5c61 100644 --- a/src/components/molecules/ChatMessageBox/ChatMessageBox.scss +++ b/src/components/molecules/ChatMessageBox/ChatMessageBox.scss @@ -12,7 +12,8 @@ } &__input { - width: 100%; + text-align: left; + padding-left: $spacing--lg; } &__submit-button { diff --git a/src/components/molecules/ChatMessageBox/ChatMessageBox.tsx b/src/components/molecules/ChatMessageBox/ChatMessageBox.tsx index 07ec1c58ee..5ebc6e06ce 100644 --- a/src/components/molecules/ChatMessageBox/ChatMessageBox.tsx +++ b/src/components/molecules/ChatMessageBox/ChatMessageBox.tsx @@ -111,7 +111,7 @@ export const ChatMessageBox: React.FC = ({ onSubmit={hasChosenThread ? sendReplyToThread : sendMessageToChat} > = ({ hasBackButton = true }) => { overlay={ProfilePopover} rootClose={true} > - + )} diff --git a/src/components/organisms/AppRouter/AdminSubrouter.tsx b/src/components/organisms/AppRouter/AdminSubrouter.tsx index 935f637ec6..7d622ddc95 100644 --- a/src/components/organisms/AppRouter/AdminSubrouter.tsx +++ b/src/components/organisms/AppRouter/AdminSubrouter.tsx @@ -19,31 +19,31 @@ export const AdminSubrouter: React.FC = () => { {/* Admin V1 */} - + - + - + - + - + @@ -57,19 +57,19 @@ export const AdminSubrouter: React.FC = () => { - + - + - + diff --git a/src/components/organisms/AppRouter/Provided.tsx b/src/components/organisms/AppRouter/Provided.tsx index 8a3d4f8c1c..5ace6697d1 100644 --- a/src/components/organisms/AppRouter/Provided.tsx +++ b/src/components/organisms/AppRouter/Provided.tsx @@ -7,34 +7,34 @@ import { RelatedVenuesProviderProps, } from "hooks/useRelatedVenues"; -export interface EmptyProviderProps { - venueId?: string; -} +export type EmptyProviderProps = Partial< + RelatedVenuesProviderProps & WorldUsersProviderProps +>; const EmptyProvider: React.FC = ({ children }) => { return <>{children}; }; export interface ProvidedProps { - withWorldUsers?: boolean; withRelatedVenues?: boolean; + withWorldUsers?: boolean; } export const Provided: React.FC = ({ - withWorldUsers = false, - withRelatedVenues = false, children, + withRelatedVenues = false, + withWorldUsers = false, }) => { const venueId = useVenueId(); - const MaybeWorldUsersProvider: React.FC = withWorldUsers - ? WorldUsersProvider - : EmptyProvider; - const MaybeRelatedVenuesProvider: React.FC = withRelatedVenues ? RelatedVenuesProvider : EmptyProvider; + const MaybeWorldUsersProvider: React.FC = withWorldUsers + ? WorldUsersProvider + : EmptyProvider; + return ( diff --git a/src/components/organisms/EventModal/EventModal.tsx b/src/components/organisms/EventModal/EventModal.tsx index b79129070d..46802be8f1 100644 --- a/src/components/organisms/EventModal/EventModal.tsx +++ b/src/components/organisms/EventModal/EventModal.tsx @@ -17,7 +17,6 @@ import { } from "utils/url"; import { useInterval } from "hooks/useInterval"; - import { useRelatedVenues } from "hooks/useRelatedVenues"; import { useRoom } from "hooks/useRoom"; diff --git a/src/components/organisms/ProfileModal/UserInformationContent/UserInformationContent.tsx b/src/components/organisms/ProfileModal/UserInformationContent/UserInformationContent.tsx index c0e1e88889..fa65b2436a 100644 --- a/src/components/organisms/ProfileModal/UserInformationContent/UserInformationContent.tsx +++ b/src/components/organisms/ProfileModal/UserInformationContent/UserInformationContent.tsx @@ -133,7 +133,7 @@ export const UserInformationContent: React.FunctionComponentMy Profile
- +

diff --git a/src/components/organisms/UserProfileModal/UserProfileModal.tsx b/src/components/organisms/UserProfileModal/UserProfileModal.tsx index b14f9d59e3..af7197a182 100644 --- a/src/components/organisms/UserProfileModal/UserProfileModal.tsx +++ b/src/components/organisms/UserProfileModal/UserProfileModal.tsx @@ -169,7 +169,6 @@ const SuspectedLocation: React.FC<{ const { relatedVenues } = useRelatedVenues({ currentVenueId: currentVenue.id, }); - const { userLocation } = useWorldUserLocation(user.id); const { lastSeenIn } = userLocation ?? {}; diff --git a/src/components/templates/Playa/Playa.tsx b/src/components/templates/Playa/Playa.tsx index 92d5491080..166a4d07ce 100644 --- a/src/components/templates/Playa/Playa.tsx +++ b/src/components/templates/Playa/Playa.tsx @@ -14,7 +14,6 @@ import { throttle } from "lodash"; import { IS_BURN } from "secrets"; import { - DEFAULT_MAP_ICON_URL, PLAYA_TEMPLATES, PLAYA_VENUE_SIZE, PLAYA_VENUE_NAME, @@ -37,12 +36,8 @@ import { } from "types/venues"; import { WithId } from "utils/id"; -// import { updateLocationData } from "utils/userLocation"; -import { - currentVenueSelectorData, - orderedVenuesSelector, -} from "utils/selectors"; -// import { getCurrentTimeInUTCSeconds } from "utils/time"; +import { currentVenueSelectorData } from "utils/selectors"; +import { isTruthy } from "utils/types"; import { peopleAttending, peopleByLastSeenIn } from "utils/venue"; import { useInterval } from "hooks/useInterval"; @@ -50,7 +45,6 @@ import { useSelector } from "hooks/useSelector"; import { useRecentVenueUsers } from "hooks/users"; import { useSynchronizedRef } from "hooks/useSynchronizedRef"; import { useUser } from "hooks/useUser"; -import { useFirestoreConnect } from "hooks/useFirestoreConnect"; import { DustStorm } from "components/organisms/DustStorm/DustStorm"; @@ -62,7 +56,6 @@ import { UserList } from "components/molecules/UserList"; import AvatarLayer from "./AvatarLayer"; import { PlayaBackground } from "./PlayaBackground"; import { PlayaIconComponent } from "./PlayaIcon"; -// import VenuePreview from "./VenuePreview"; import VideoChatLayer from "./VideoChatLayer"; import "./Playa.scss"; @@ -125,11 +118,9 @@ const isPlaced = (venue: AnyVenue) => { const minZoom = () => (window.innerWidth - 2 * PLAYA_MARGIN_X) / PLAYA_WIDTH; -const Playa = () => { - // @debt This will currently load all venues in firebase into memory.. not very efficient - useFirestoreConnect("venues"); - const venues = useSelector(orderedVenuesSelector); +const venues = [] as WithId[]; +const Playa = () => { const venue = useSelector(currentVenueSelectorData); const [showModal, setShowModal] = useState(false); @@ -354,12 +345,6 @@ const Playa = () => { const hideVenue = useCallback(() => { setShowModal(false); - // user && - // updateLocationData( - // user, - // { [PLAYA_VENUE_NAME]: getCurrentTimeInUTCSeconds() }, - // profile?.lastSeenIn - // ); }, [setShowModal]); const distanceToVenue = ( @@ -388,7 +373,7 @@ const Playa = () => { showVenue(campVenue); } } - }, [camp, venues, showVenue]); + }, [camp, showVenue]); const [openVenues, setOpenVenues] = useState(); @@ -403,7 +388,6 @@ const Playa = () => { ? openVenues.filter((v) => !v.venue.adultContent) : openVenues ); - //setOpenVenues(openVenues); }) .catch(Bugsnag.notify); }, REFETCH_SCHEDULE_MS); @@ -527,26 +511,27 @@ const Playa = () => { }); }, [myXRef, myYRef]); - const getNearbyVenue = useCallback( - (x: number, y: number) => { - if (!venues) return; - let closestVenue: WithId | undefined; - let distanceToClosestVenue: number; - venues.forEach((venue) => { - const distance = distanceToVenue(x, y, venue.placement); - if ( - distance && - distance <= VENUE_NEARBY_DISTANCE && - (!distanceToClosestVenue || distance < distanceToClosestVenue) - ) { - closestVenue = venue; - distanceToClosestVenue = distance; - } - }); - return closestVenue; - }, - [venues] - ); + const getNearbyVenue = useCallback((x: number, y: number) => { + if (!venues) return; + + let closestVenue: WithId | undefined; + let distanceToClosestVenue: number; + + venues.forEach((venue) => { + const distance = distanceToVenue(x, y, venue.placement); + + if ( + isTruthy(distance) && + distance <= VENUE_NEARBY_DISTANCE && + (!distanceToClosestVenue || distance < distanceToClosestVenue) + ) { + closestVenue = venue; + distanceToClosestVenue = distance; + } + }); + + return closestVenue; + }, []); const setMyLocation = useMemo( () => (x: number, y: number) => { @@ -590,11 +575,6 @@ const Playa = () => { {venues?.filter(isPlaced).map((v, idx) => { // @debt This isn't strictly correct here.. but this is an unused legacy template soon to be deleted, so we don't mind const usersInVenue = recentVenueUsers; - // const usersInVenue = recentVenueUsers.filter( - // (partygoer) => - // partygoer.lastSeenIn?.[v.name] > - // (nowMs - LOC_UPDATE_FREQ_MS * 2) / 1000 - // ); return ( <>
{ }} onMouseLeave={() => setShowVenueTooltip(false)} > - + {/* Removed as unnecessary. https://github.com/sparkletown/internal-sparkle-issues/issues/710 */} + {/* {`${v.name} + /> */} {selectedVenueId === v.id &&
}
@@ -768,7 +749,6 @@ const Playa = () => { showUserTooltip, showVenueTooltip, venue, - venues, openVenues, showVenue, recentVenueUsers, diff --git a/src/components/templates/Playa/PlayaVenue.tsx b/src/components/templates/Playa/PlayaVenue.tsx index 96813c91b5..b8686a5184 100644 --- a/src/components/templates/Playa/PlayaVenue.tsx +++ b/src/components/templates/Playa/PlayaVenue.tsx @@ -1,6 +1,6 @@ import React, { useRef } from "react"; import { Overlay } from "react-bootstrap"; -import { DEFAULT_MAP_ICON_URL, PLAYA_VENUE_SIZE } from "settings"; +import { PLAYA_VENUE_SIZE } from "settings"; import { AnyVenue } from "types/venues"; import { WithId } from "utils/id"; @@ -36,12 +36,13 @@ const PlayaVenue = ({ onMouseOver={onMouseOver} onMouseLeave={onMouseLeave} > - + {/* Removed as unnecessary. https://github.com/sparkletown/internal-sparkle-issues/issues/710 */} + {/* {`${venue.name} + /> */} {selectedVenueId === venue.id &&
}
diff --git a/src/hooks/useAdminVenues.ts b/src/hooks/useAdminVenues.ts deleted file mode 100644 index 796e2d2e9e..0000000000 --- a/src/hooks/useAdminVenues.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { useFirestoreConnect } from "hooks/useFirestoreConnect"; - -export const useAdminVenues = (userUid?: string) => { - useFirestoreConnect({ - collection: "venues", - where: [["owners", "array-contains", userUid || ""]], - }); -}; diff --git a/src/hooks/useConnectOwnedVenues.tsx b/src/hooks/useConnectOwnedVenues.tsx new file mode 100644 index 0000000000..fa6dfa02e9 --- /dev/null +++ b/src/hooks/useConnectOwnedVenues.tsx @@ -0,0 +1,86 @@ +import { useMemo, useCallback } from "react"; +import { ReactHook } from "types/utility"; +import { AnyVenue } from "types/venues"; + +import { WithId, withId } from "utils/id"; +import { ownedVenuesDataSelector, ownedVenuesSelector } from "utils/selectors"; + +import { useFirestoreConnect, isLoaded } from "hooks/useFirestoreConnect"; +import { useSelector } from "hooks/useSelector"; +import { useUser } from "hooks/useUser"; + +export const useConnectOwnedVenues = (userId?: string) => { + useFirestoreConnect( + userId + ? { + collection: "venues", + where: [["owners", "array-contains", userId]], + storeAs: "ownedVenues", + } + : undefined + ); +}; + +export interface UseOwnedVenuesProps { + currentVenueId?: string; +} + +export interface UseOwnedVenuesData { + isLoaded: boolean; + isLoading: boolean; + + currentVenue?: WithId; + + ownedVenues: WithId[]; + ownedVenuesIds: string[]; + + findVenueInOwnedVenues: ( + searchedForVenueId: string + ) => WithId | undefined; +} + +export const useOwnedVenues: ReactHook< + UseOwnedVenuesProps, + UseOwnedVenuesData +> = ({ currentVenueId }): UseOwnedVenuesData => { + const { userId } = useUser(); + useConnectOwnedVenues(userId); + + const ownedVenuesData = useSelector(ownedVenuesDataSelector); + const ownedVenues = useSelector(ownedVenuesSelector); + + const ownedVenuesIds = useMemo(() => Object.keys(ownedVenuesData ?? {}), [ + ownedVenuesData, + ]); + + const findVenueInOwnedVenues = useCallback( + (searchedForVenueId: string) => { + const foundVenue = ownedVenuesData?.[searchedForVenueId]; + return foundVenue ? withId(foundVenue, searchedForVenueId) : undefined; + }, + [ownedVenuesData] + ); + + return useMemo( + () => ({ + isLoaded: isLoaded(ownedVenuesData), + isLoading: !isLoaded(ownedVenuesData), + + ownedVenues: ownedVenues ?? [], + ownedVenuesIds, + + currentVenue: currentVenueId + ? findVenueInOwnedVenues(currentVenueId) + : undefined, + + findVenueInOwnedVenues, + }), + [ + ownedVenues, + ownedVenuesIds, + findVenueInOwnedVenues, + currentVenueId, + ownedVenuesData, + ] + ); +}; diff --git a/src/hooks/usePreloadAssets.ts b/src/hooks/usePreloadAssets.ts new file mode 100644 index 0000000000..41ab6d1dfb --- /dev/null +++ b/src/hooks/usePreloadAssets.ts @@ -0,0 +1,41 @@ +import { useEffect, useRef } from "react"; + +import { isDefined } from "utils/types"; + +export interface PreloadAsset { + url: string; + as?: string; + type?: string; +} + +const createLinkElement = ({ url, type, as = "image" }: PreloadAsset) => { + const link: HTMLLinkElement = document.createElement("link"); + + link.rel = "preload"; + link.as = as; + link.href = url; + + if (isDefined(type)) { + link.type = type; + } + + return link; +}; + +export const usePreloadAssets = (assets: PreloadAsset[]) => { + const headRef = useRef(document.head); + + useEffect(() => { + const links = assets.map((asset) => { + const link = createLinkElement(asset); + headRef.current.appendChild(link); + return link; + }); + + return () => { + for (const link of links) { + link.remove(); + } + }; + }, [assets]); +}; diff --git a/src/hooks/useRoom.ts b/src/hooks/useRoom.ts index ba97549a6b..a125647588 100644 --- a/src/hooks/useRoom.ts +++ b/src/hooks/useRoom.ts @@ -3,11 +3,10 @@ import { useCallback, useMemo } from "react"; import { Room } from "types/rooms"; import { enterExternalRoom } from "utils/userLocation"; -import { orderedVenuesSelector } from "utils/selectors"; import { enterVenue } from "utils/url"; import { getExternalRoomSlug } from "utils/room"; -import { useSelector } from "hooks/useSelector"; +import { useRelatedVenues } from "hooks/useRelatedVenues"; import { useRecentLocationUsers } from "hooks/users"; import { useUser } from "hooks/useUser"; @@ -15,19 +14,19 @@ export interface UseRoomProps { room?: Room; venueName: string; } - +// @debt refactor useRoom to take venueId instead of venueName export const useRoom = ({ room, venueName }: UseRoomProps) => { const { user } = useUser(); const userId = user?.uid; const roomUrl = room?.url ?? ""; - // @debt This selector relies on all venues in firebase being loaded into memory.. not very efficient - const venues = useSelector(orderedVenuesSelector); + // @debt pass venueId taken from UseRoomProps through to useRelatedVenues + const { relatedVenues } = useRelatedVenues({}); const roomVenue = useMemo( - () => venues?.find((venue) => roomUrl.endsWith(`/${venue.id}`)), - [roomUrl, venues] + () => relatedVenues.find((venue) => roomUrl.endsWith(`/${venue.id}`)), + [roomUrl, relatedVenues] ); // @debt we should replace externalRoomSlug with preferrably room id diff --git a/src/pages/Account/Venue/VenueMapEdition/Container.tsx b/src/pages/Account/Venue/VenueMapEdition/Container.tsx index 0222d8d499..11b167543a 100644 --- a/src/pages/Account/Venue/VenueMapEdition/Container.tsx +++ b/src/pages/Account/Venue/VenueMapEdition/Container.tsx @@ -24,7 +24,7 @@ export interface SubVenueIconMap { [key: string]: { top: number; left: number; - url: string; + url?: string; width: number; height: number; roomIndex?: number; diff --git a/src/pages/Account/Venue/VenueMapEdition/PlayaContainer.tsx b/src/pages/Account/Venue/VenueMapEdition/PlayaContainer.tsx index 7e49297772..fe8cc583b1 100644 --- a/src/pages/Account/Venue/VenueMapEdition/PlayaContainer.tsx +++ b/src/pages/Account/Venue/VenueMapEdition/PlayaContainer.tsx @@ -39,7 +39,6 @@ export const PlayaContainer: React.FC = (props) => { height: v.height ? (v.height / PLAYA_HEIGHT) * 100 : 2, top: v.placement?.y, left: v.placement?.x, - url: v.mapIconImageUrl, }, }; }, {}) ?? {} diff --git a/src/pages/Admin/Admin.tsx b/src/pages/Admin/Admin.tsx index ee95358655..c141414f86 100644 --- a/src/pages/Admin/Admin.tsx +++ b/src/pages/Admin/Admin.tsx @@ -5,7 +5,6 @@ import React, { useRef, useState, } from "react"; -import { shallowEqual } from "react-redux"; import { Link, Redirect, @@ -36,7 +35,6 @@ import { isVenueWithRooms, AnyVenue, VenueEvent } from "types/venues"; import { isTruthyFilter } from "utils/filter"; import { WithId } from "utils/id"; -import { makeVenueSelector, orderedVenuesSelector } from "utils/selectors"; import { venueInsideUrl } from "utils/url"; import { canBeDeleted, @@ -45,10 +43,10 @@ import { canHaveSubvenues, } from "utils/venue"; +import { useOwnedVenues } from "hooks/useConnectOwnedVenues"; import { useFirestoreConnect } from "hooks/useFirestoreConnect"; import { useIsAdminUser } from "hooks/roles"; import { useQuery } from "hooks/useQuery"; -import { useSelector } from "hooks/useSelector"; import { useShowHide } from "hooks/useShowHide"; import { useUser } from "hooks/useUser"; import { useVenueId } from "hooks/useVenueId"; @@ -56,6 +54,7 @@ import { useVenueId } from "hooks/useVenueId"; import { PlayaContainer } from "pages/Account/Venue/VenueMapEdition"; import WithNavigationBar from "components/organisms/WithNavigationBar"; +import { Loading } from "components/molecules/Loading"; import AdminDeleteEvent from "./AdminDeleteEvent"; import AdminEventModal from "./AdminEventModal"; @@ -77,10 +76,11 @@ const VenueList: React.FC = ({ selectedVenueId, roomIndex, }) => { - // @debt This selector relies on all venues in firebase being loaded into memory.. not very efficient - const venues = useSelector(orderedVenuesSelector); + const { isLoading, ownedVenues } = useOwnedVenues({ + currentVenueId: selectedVenueId, + }); - if (!venues) return <>Loading...; + if (isLoading) return ; return ( <> @@ -91,11 +91,11 @@ const VenueList: React.FC = ({
    - {venues.map((venue, index) => ( + {ownedVenues.map((venue) => (
  • {venue.name} @@ -129,11 +129,7 @@ const VenueDetails: React.FC = ({ venueId, roomIndex }) => { const { url: matchUrl } = useRouteMatch(); const { pathname: urlPath } = useLocation(); - const venueSelector = useCallback( - (state) => makeVenueSelector(venueId)(state), - [venueId] - ); - const venue = useSelector(venueSelector, shallowEqual); + const { currentVenue } = useOwnedVenues({ currentVenueId: venueId }); const [showCreateEventModal, setShowCreateEventModal] = useState(false); const [showDeleteEventModal, setShowDeleteEventModal] = useState(false); @@ -150,19 +146,22 @@ const VenueDetails: React.FC = ({ venueId, roomIndex }) => { }, []); const tabs = useMemo(() => { - if (!venue) return []; + if (!currentVenue) return []; return [ { url: matchUrl, label: "Venue Info" }, - canHaveEvents(venue) && { url: `${matchUrl}/events`, label: "Events" }, - canHavePlacement(venue) && { + canHaveEvents(currentVenue) && { + url: `${matchUrl}/events`, + label: "Events", + }, + canHavePlacement(currentVenue) && { url: `${matchUrl}/placement`, label: "Placement & Editing", }, ].filter(isTruthyFilter); - }, [matchUrl, venue]); + }, [matchUrl, currentVenue]); - if (!venue) { + if (!currentVenue) { return <>{"Oops, seems we can't find your venue!"}; } @@ -184,7 +183,7 @@ const VenueDetails: React.FC = ({ venueId, roomIndex }) => { = ({ venueId, roomIndex }) => { = ({ venueId, roomIndex }) => { onHide={adminEventModalOnHide} venueId={venueId} event={editedEvent} - template={venue.template} + template={currentVenue.template} setEditedEvent={setEditedEvent} setShowDeleteEventModal={setShowDeleteEventModal} /> @@ -297,14 +296,13 @@ const VenueInfoComponent: React.FC = ({ interactive={false} resizable={false} iconsMap={ - venue.placement && venue.mapIconImageUrl + venue.placement ? { icon: { width: PLAYA_VENUE_SIZE, height: PLAYA_VENUE_SIZE, top: venue.placement.y, left: venue.placement.x, - url: venue.mapIconImageUrl, }, } : {} diff --git a/src/pages/Admin/AdminVenuePreview.tsx b/src/pages/Admin/AdminVenuePreview.tsx index bf0870c1e9..e899e5b80b 100644 --- a/src/pages/Admin/AdminVenuePreview.tsx +++ b/src/pages/Admin/AdminVenuePreview.tsx @@ -3,12 +3,7 @@ import { AnyVenue, PartyMapVenue, VenueTemplate } from "types/venues"; import { WithId } from "utils/id"; import { PartyMapContainer } from "pages/Account/Venue/VenueMapEdition"; import { ConvertToEmbeddableUrl } from "utils/ConvertToEmbeddableUrl"; -import { - IFRAME_ALLOW, - PLAYA_IMAGE, - PLAYA_VENUE_NAME, - PLAYA_VENUE_STYLES, -} from "settings"; +import { IFRAME_ALLOW, PLAYA_IMAGE, PLAYA_VENUE_STYLES } from "settings"; import { RenderMarkdown } from "components/organisms/RenderMarkdown"; @@ -75,7 +70,7 @@ export const AdminVenuePreview: React.FC = ({ return (
    - This is a preview of your camp + This is a preview of your Space = ({ />

-
+ {/* Removed as unnecessary. https://github.com/sparkletown/internal-sparkle-issues/issues/710 */} + {/*
{PLAYA_VENUE_NAME} icon
icon
-
+
*/}
- Camp logo + Square logo
icon diff --git a/src/pages/Admin/Admin_v2.tsx b/src/pages/Admin/Admin_v2.tsx index 4afa15c3a7..19fe322fe0 100644 --- a/src/pages/Admin/Admin_v2.tsx +++ b/src/pages/Admin/Admin_v2.tsx @@ -3,13 +3,10 @@ import "firebase/storage"; import dayjs from "dayjs"; import advancedFormat from "dayjs/plugin/advancedFormat"; -import { orderedVenuesSelector } from "utils/selectors"; - -import { useSelector } from "hooks/useSelector"; +import { useOwnedVenues } from "hooks/useConnectOwnedVenues"; import { useUser } from "hooks/useUser"; import { useRoles } from "hooks/useRoles"; import { useIsAdminUser } from "hooks/roles"; -import { useAdminVenues } from "hooks/useAdminVenues"; import { AdminVenues } from "components/organisms/AdminVenues/AdminVenues"; import { @@ -25,16 +22,14 @@ dayjs.extend(advancedFormat); const Admin_v2: React.FC = () => { const { user } = useUser(); - useAdminVenues(user?.uid); - // @debt This selector relies on all venues in firebase being loaded into memory.. not very efficient - const venues = useSelector(orderedVenuesSelector); + const { ownedVenues, isLoading } = useOwnedVenues({}); const { roles } = useRoles(); const { isAdminUser } = useIsAdminUser(user?.uid); - if (!venues || !roles) { + if (isLoading || !roles) { return ; } @@ -50,7 +45,7 @@ const Admin_v2: React.FC = () => { <> - + diff --git a/src/pages/Admin/Details/ValidationSchema.ts b/src/pages/Admin/Details/ValidationSchema.ts index c46c5310ee..3097db8d37 100644 --- a/src/pages/Admin/Details/ValidationSchema.ts +++ b/src/pages/Admin/Details/ValidationSchema.ts @@ -61,15 +61,6 @@ const createFileSchema = ( } ); -const urlIfNoFileValidation = (fieldName: string) => - Yup.string().when( - fieldName, - (file: FileList | undefined, schema: Yup.MixedSchema) => - file && file.length > 0 - ? schema.notRequired() - : schema.required("Required") - ); - const mustBeMinimum = (fieldName: string, min: number) => `${fieldName} must be at least ${min} characters`; @@ -221,26 +212,17 @@ export const editVenueCastSchema = Yup.object() // possible locations for the banner image .from("config.landingPageConfig.coverImageUrl", "bannerImageUrl") - .from("config.landingPageConfig.bannerImageUrl", "bannerImageUrl") - - // possible locations for the map icon - .from("config.mapIconImageUrl", "mapIconImageUrl") - .from("mapIconImageUrl", "mapIconImageUrl"); + .from("config.landingPageConfig.bannerImageUrl", "bannerImageUrl"); // @debt I'm pretty sure every one of these .from that have the same fromKey / toKey are redundant noops and should be removed export const editPlacementCastSchema = Yup.object() .shape>({}) - // possible locations for the map icon - .from("config.mapIconImageUrl", "mapIconImageUrl") - .from("mapIconImageUrl", "mapIconImageUrl") .from("placement.addressText", "addressText") .from("placement.notes", "notes") .required(); export const editPlacementSchema = Yup.object().shape({ - mapIconImageFile: createFileSchema("mapIconImageFile", false).notRequired(), - mapIconImageUrl: urlIfNoFileValidation("mapIconImageFile"), addressText: Yup.string(), notes: Yup.string(), width: Yup.number().required("Required"), diff --git a/src/pages/Admin/Venue/DetailsForm.tsx b/src/pages/Admin/Venue/DetailsForm.tsx index 93a7c12922..f380ca0b26 100644 --- a/src/pages/Admin/Venue/DetailsForm.tsx +++ b/src/pages/Admin/Venue/DetailsForm.tsx @@ -250,26 +250,16 @@ export const DetailsForm: React.FC = ({ ] ); - const mapIconUrl = useMemo(() => { - const file = values.mapIconImageFile; - if (file && file.length > 0) return URL.createObjectURL(file[0]); - return values.mapIconImageUrl; - }, [values.mapIconImageFile, values.mapIconImageUrl]); - const iconsMap = useMemo( - () => - mapIconUrl - ? { - [iconPositionFieldName]: { - width: PLAYA_VENUE_SIZE, - height: PLAYA_VENUE_SIZE, - top: defaultValues?.placement?.y ?? 0, - left: defaultValues?.placement?.x ?? 0, - url: mapIconUrl, - }, - } - : undefined, - [mapIconUrl, defaultValues] + () => ({ + [iconPositionFieldName]: { + width: PLAYA_VENUE_SIZE, + height: PLAYA_VENUE_SIZE, + top: defaultValues?.placement?.y ?? 0, + left: defaultValues?.placement?.x ?? 0, + }, + }), + [defaultValues] ); const onBoxMove: ExtractProps< diff --git a/src/pages/Admin/Venue/DetailsValidationSchema.ts b/src/pages/Admin/Venue/DetailsValidationSchema.ts index ad39c190d7..aeaa5bec96 100644 --- a/src/pages/Admin/Venue/DetailsValidationSchema.ts +++ b/src/pages/Admin/Venue/DetailsValidationSchema.ts @@ -220,11 +220,8 @@ export const editVenueCastSchema = Yup.object() .from("config.landingPageConfig.coverImageUrl", "bannerImageUrl") .from("config.landingPageConfig.bannerImageUrl", "bannerImageUrl") - // possible locations for the map icon - .from("config.mapIconImageUrl", "mapIconImageUrl") .from("auditoriumColumns", "auditoriumColumns") .from("auditoriumRows", "auditoriumRows") - .from("mapIconImageUrl", "mapIconImageUrl") .from("code_of_conduct_questions", "code_of_conduct_questions") .from("profile_questions", "profile_questions"); @@ -232,16 +229,11 @@ export const editVenueCastSchema = Yup.object() export const editPlacementCastSchema = Yup.object() .shape>({}) - // possible locations for the map icon - .from("config.mapIconImageUrl", "mapIconImageUrl") - .from("mapIconImageUrl", "mapIconImageUrl") .from("placement.addressText", "addressText") .from("placement.notes", "notes") .required(); export const editPlacementSchema = Yup.object().shape({ - mapIconImageFile: createFileSchema("mapIconImageFile", false).notRequired(), - mapIconImageUrl: urlIfNoFileValidation("mapIconImageFile"), addressText: Yup.string(), notes: Yup.string(), width: Yup.number().required("Required"), diff --git a/src/pages/Admin/Venue/Rooms/RoomsForm.tsx b/src/pages/Admin/Venue/Rooms/RoomsForm.tsx index b19520015c..cb5105a181 100644 --- a/src/pages/Admin/Venue/Rooms/RoomsForm.tsx +++ b/src/pages/Admin/Venue/Rooms/RoomsForm.tsx @@ -264,7 +264,7 @@ const RoomInnerForm: React.FC = (props) => {
Upload an image for how your room should appear on the - camp map + Space map
= (props) => { className="italic" style={{ textAlign: "center", fontSize: "22px" }} > - Position your room in the camp + Position your room in the Space

First upload or select the icon you would like to appear in your diff --git a/src/pages/Admin/VenueList/VenueList.tsx b/src/pages/Admin/VenueList/VenueList.tsx deleted file mode 100644 index b5a6980474..0000000000 --- a/src/pages/Admin/VenueList/VenueList.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import { Link } from "react-router-dom"; - -import { isVenueWithRooms } from "types/venues"; - -import { orderedVenuesSelector } from "utils/selectors"; -import { canHaveSubvenues } from "utils/venue"; - -import { useSelector } from "hooks/useSelector"; - -import { VenueListProps } from "./VenueList.types"; - -const VenueList: React.FC = ({ - selectedVenueId, - roomIndex, -}) => { - // @debt This selector relies on all venues in firebase being loaded into memory.. not very efficient - const venues = useSelector(orderedVenuesSelector); - - if (!venues) return <>Loading...; - - return ( - <> -

My Venues
-
- - Create a venue - -
-
    - {venues.map((venue, index) => ( -
  • - {venue.name} - {isVenueWithRooms(venue) && venue.rooms && ( -
      - {venue.rooms.map((room, idx) => ( -
    • - - {room.title} - -
    • - ))} -
    - )} -
  • - ))} -
- - ); -}; - -export default VenueList; diff --git a/src/pages/Admin/VenueList/VenueList.types.ts b/src/pages/Admin/VenueList/VenueList.types.ts deleted file mode 100644 index 729fbe1221..0000000000 --- a/src/pages/Admin/VenueList/VenueList.types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type VenueListProps = { - selectedVenueId?: string; - roomIndex?: number; -}; diff --git a/src/pages/Admin/VenueList/index.ts b/src/pages/Admin/VenueList/index.ts deleted file mode 100644 index 1cf257e456..0000000000 --- a/src/pages/Admin/VenueList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./VenueList"; diff --git a/src/pages/VenuePage/VenuePage.tsx b/src/pages/VenuePage/VenuePage.tsx index 8fab2a8555..0ad3fd029f 100644 --- a/src/pages/VenuePage/VenuePage.tsx +++ b/src/pages/VenuePage/VenuePage.tsx @@ -1,4 +1,4 @@ -import React, { Suspense, lazy, useEffect } from "react"; +import React, { Suspense, lazy, useEffect, useMemo } from "react"; import { Redirect } from "react-router-dom"; import { useTitle } from "react-use"; @@ -22,12 +22,13 @@ import { venueEntranceUrl } from "utils/url"; import { tracePromise } from "utils/performance"; import { isCompleteProfile, updateProfileEnteredVenueIds } from "utils/profile"; -import { isTruthy } from "utils/types"; +import { isTruthy, isDefined } from "utils/types"; import { hasEventFinished, isEventStartingSoon } from "utils/event"; import { useConnectCurrentEvent } from "hooks/useConnectCurrentEvent"; import { useInterval } from "hooks/useInterval"; import { useMixpanel } from "hooks/useMixpanel"; +import { usePreloadAssets } from "hooks/usePreloadAssets"; import { useSelector } from "hooks/useSelector"; import { useWorldUserLocation } from "hooks/users"; import { useUser } from "hooks/useUser"; @@ -81,6 +82,19 @@ export const VenuePage: React.FC = () => { const venue = useSelector(currentVenueSelector); const venueRequestStatus = useSelector(isCurrentVenueRequestedSelector); + const assetsToPreload = useMemo( + () => + [ + venue?.mapBackgroundImageUrl, + ...(venue?.rooms ?? []).map((room) => room?.image_url), + ] + .filter(isDefined) + .map((url) => ({ url })), + [venue] + ); + + usePreloadAssets(assetsToPreload); + useConnectCurrentEvent(); const currentEvent = useSelector(currentEventSelector); const eventRequestStatus = useSelector(isCurrentEventRequestedSelector); @@ -173,6 +187,7 @@ export const VenuePage: React.FC = () => { } if (!venue || !venueId) { + // @debt if !venueId is true loading page might display indefinitely, another message or action may be appropriate return ; } diff --git a/src/scss/constants.scss b/src/scss/constants.scss index d7406e75af..2549d13620 100644 --- a/src/scss/constants.scss +++ b/src/scss/constants.scss @@ -239,3 +239,12 @@ $z-layers: ( overflow: hidden; text-overflow: ellipsis; } + +@mixin square-size($size: 1, $min: null, $max: null) { + height: $size; + width: $size; + min-height: $min; + min-width: $min; + max-height: $max; + max-width: $max; +} diff --git a/src/settings.ts b/src/settings.ts index d4d7107b9d..b8cae07b53 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -184,6 +184,7 @@ export const IFRAME_TEMPLATES = [ VenueTemplate.firebarrel, VenueTemplate.jazzbar, VenueTemplate.performancevenue, + VenueTemplate.posterpage, ]; // @debt Refactor this constant into types/venues + create an actual custom type grouping for it diff --git a/src/types/Firestore.ts b/src/types/Firestore.ts index e7fb8641c3..f12c4b4dbe 100644 --- a/src/types/Firestore.ts +++ b/src/types/Firestore.ts @@ -62,6 +62,7 @@ export interface FirestoreData { currentAuditoriumSections?: Partial>; events?: Record; experience?: Experience; + ownedVenues?: Record; playaVenues?: Record; // for the admin playa preview reactions?: Record; screeningRoomVideos: Record; @@ -90,6 +91,7 @@ export interface FirestoreOrdered { currentAuditoriumSections?: WithId[]; events?: WithId[]; experience: WithId; + ownedVenues?: WithId[]; parentVenueEvents?: WithId[]; playaVenues?: WithId[]; reactions?: WithId[]; diff --git a/src/types/venues.ts b/src/types/venues.ts index 18973d8c8a..200e8e35b9 100644 --- a/src/types/venues.ts +++ b/src/types/venues.ts @@ -129,7 +129,6 @@ export interface BaseVenue { owners: string[]; iframeUrl?: string; events?: Array; //@debt typing is this optional? I have a feeling this no longer exists @chris confirm - mapIconImageUrl?: string; placement?: VenuePlacement; zoomUrl?: string; mapBackgroundImageUrl?: string; diff --git a/src/utils/address.ts b/src/utils/address.ts index e93523ed7d..f4e208157c 100644 --- a/src/utils/address.ts +++ b/src/utils/address.ts @@ -87,7 +87,7 @@ const MAN: Point = { name: "The Man", evaluator: cityEvaluator, }; -const CENTER_CAMP: Point = { +const CENTER_SPACE: Point = { x: 1915, y: 2179, name: "Center Camp", @@ -115,7 +115,7 @@ const DEEP_PLAYA: Point = { const POINTS: Point[] = [ MAN, - CENTER_CAMP, + CENTER_SPACE, NORTHWEST_SATELLITE, SOUTHEAST_SATELLITE, DEEP_PLAYA, diff --git a/src/utils/selectors.ts b/src/utils/selectors.ts index ea72215460..5157ee24fc 100644 --- a/src/utils/selectors.ts +++ b/src/utils/selectors.ts @@ -86,51 +86,6 @@ export const worldUsersByIdWithoutLocationSelector: SparkleSelector< ); }; -/** - * Selector to retrieve venues from the Redux Firestore. - * - * @param state the Redux store - * - * @deprecated This selector requires all of the venues data in firebase to be loaded into memory. Find a different way. - * @debt Refactor all places that rely on this, then remove it from the codebase - */ -export const venuesSelector: SparkleSelector> = ( - state -) => state.firestore.data.venues || {}; - -/** - * @deprecated This selector requires all of the venues data in firebase to be loaded into memory. Find a different way. - * @debt Refactor all places that rely on this, then remove it from the codebase - */ -export const orderedVenuesSelector: SparkleSelector< - WithId[] | undefined -> = (state) => state.firestore.ordered.venues; - -/** - * Makes a venueSelector selector for a given venueId, which when called - * will retrieve the specified venue from the Redux Firestore. - * - * @param venueId the venueId to be retrieved - * @return (state: RootState) => WithId | undefined - * - * @example - * const venueId = 'abc123' - * const venueSelector = useCallback(makeVenueSelector(venueId), [venueId]) - * const venue = useSelector(venueSelector, shallowEqual) - * - * @deprecated This function relies on a selector that requires all of the venues data in firebase to be loaded into memory. Find a different way. - * @debt Refactor all places that rely on this, then remove it from the codebase - */ -export const makeVenueSelector = (venueId: string) => ( - state: RootState -): WithId | undefined => { - const venues = venuesSelector(state); - - if (!venues.hasOwnProperty(venueId)) return undefined; - - return { ...venues[venueId], id: venueId }; -}; - export const currentEventSelector: SparkleSelector< WithId[] | undefined > = makeOrderedSelector("currentEvent"); @@ -254,3 +209,11 @@ export const noopSelector: SparkleSelector = () => undefined; export const emptyArray = []; export const emptyArraySelector = (): T[] => emptyArray; + +export const ownedVenuesDataSelector: SparkleSelector< + Record | undefined +> = (state) => state.firestore.data.ownedVenues; + +export const ownedVenuesSelector: SparkleSelector< + WithId[] | undefined +> = (state) => state.firestore.ordered.ownedVenues; diff --git a/src/utils/venue.ts b/src/utils/venue.ts index 0b28f166c3..9d3b51762a 100644 --- a/src/utils/venue.ts +++ b/src/utils/venue.ts @@ -74,10 +74,6 @@ export const createJazzbar = (values: FormValues): JazzbarVenue => { return { template: VenueTemplate.jazzbar, name: values.name || "Your Jazz Bar", - mapIconImageUrl: urlFromImage( - "/default-profile-pic.png", - values.mapIconImageFile - ), config: { theme: { primaryColor: "yellow",