diff --git a/res/css/views/messages/_MLocationBody.scss b/res/css/views/messages/_MLocationBody.scss index 948822bea8a..0a25d0ada08 100644 --- a/res/css/views/messages/_MLocationBody.scss +++ b/res/css/views/messages/_MLocationBody.scss @@ -40,4 +40,16 @@ limitations under the License. bottom: -3px; left: 12px; } + + .mx_MLocationBody_markerContents { + background-color: $location-marker-color; + margin: 4px; + width: 24px; + height: 24px; + padding-top: 8px; + mask-repeat: no-repeat; + mask-size: contain; + mask-position: center; + mask-image: url('$(res)/img/element-icons/location.svg'); + } } diff --git a/res/img/element-icons/location.svg b/res/img/element-icons/location.svg new file mode 100644 index 00000000000..436c0e637bf --- /dev/null +++ b/res/img/element-icons/location.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss index 4760386532e..9dcb2540d3e 100644 --- a/res/themes/legacy-light/css/_legacy-light.scss +++ b/res/themes/legacy-light/css/_legacy-light.scss @@ -36,6 +36,7 @@ $accent-alt: #238cf5; $selection-fg-color: $primary-bg-color; $focus-brightness: 105%; +$location-marker-color: #ffffff; $other-user-pill-bg-color: rgba(0, 0, 0, 0.1); diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss index c1c8f31fc4e..37f5d646786 100644 --- a/res/themes/light/css/_light.scss +++ b/res/themes/light/css/_light.scss @@ -283,6 +283,7 @@ $pinned-color: $tertiary-content; $avatar-initial-color: $background; $primary-hairline-color: transparent; $focus-brightness: 105%; +$location-marker-color: #ffffff; // ******************** // blur amounts for left left panel (only for element theme) diff --git a/src/components/views/messages/MLocationBody.tsx b/src/components/views/messages/MLocationBody.tsx index a54aa8a1f1f..a2fcfe09824 100644 --- a/src/components/views/messages/MLocationBody.tsx +++ b/src/components/views/messages/MLocationBody.tsx @@ -17,8 +17,13 @@ limitations under the License. import React from 'react'; import maplibregl from 'maplibre-gl'; import { logger } from "matrix-js-sdk/src/logger"; -import { LOCATION_EVENT_TYPE } from 'matrix-js-sdk/src/@types/location'; import { MatrixEvent } from 'matrix-js-sdk/src/models/event'; +import { + ASSET_NODE_TYPE, + ASSET_TYPE_SELF, + ILocationContent, + LOCATION_EVENT_TYPE, +} from 'matrix-js-sdk/src/@types/location'; import SdkConfig from '../../../SdkConfig'; import { replaceableComponent } from "../../../utils/replaceableComponent"; @@ -101,6 +106,12 @@ export default class MLocationBody extends React.Component { } } +export function isSelfLocation(locationContent: ILocationContent): boolean { + const asset = ASSET_NODE_TYPE.findIn(locationContent) as { type: string }; + const assetType = asset?.type ?? ASSET_TYPE_SELF; + return assetType == ASSET_TYPE_SELF; +} + interface ILocationBodyContentProps { mxEvent: MatrixEvent; bodyId: string; @@ -121,6 +132,17 @@ export function LocationBodyContent(props: ILocationBodyContentProps): className="mx_MLocationBody_map" />; + const markerContents = ( + isSelfLocation(props.mxEvent.getContent()) + ? + :
+ ); + return
{ props.error @@ -142,12 +164,7 @@ export function LocationBodyContent(props: ILocationBodyContentProps): }
- + { markerContents }
{ ); }); }); + + describe("isSelfLocation", () => { + it("Returns true for a full m.asset event", () => { + const content = makeLocationContent("", "", 0); + expect(isSelfLocation(content)).toBe(true); + }); + + it("Returns true for a missing m.asset", () => { + const content = { + body: "", + msgtype: "m.location", + geo_uri: "", + [LOCATION_EVENT_TYPE.name]: { uri: "" }, + [TEXT_NODE_TYPE.name]: "", + [TIMESTAMP_NODE_TYPE.name]: 0, + // Note: no m.asset! + }; + expect(isSelfLocation(content as ILocationContent)).toBe(true); + }); + + it("Returns true for a missing m.asset type", () => { + const content = { + body: "", + msgtype: "m.location", + geo_uri: "", + [LOCATION_EVENT_TYPE.name]: { uri: "" }, + [TEXT_NODE_TYPE.name]: "", + [TIMESTAMP_NODE_TYPE.name]: 0, + [ASSET_NODE_TYPE.name]: { + // Note: no type! + }, + }; + expect(isSelfLocation(content as ILocationContent)).toBe(true); + }); + + it("Returns false for an unknown asset type", () => { + const content = makeLocationContent("", "", 0, "", "org.example.unknown"); + expect(isSelfLocation(content)).toBe(false); + }); + }); }); function oldLocationEvent(geoUri: string): MatrixEvent {