Location share type UI (#7924)

* copyright

Signed-off-by: Kerry Archibald <kerrya@element.io>

* empty line

Signed-off-by: Kerry Archibald <kerrya@element.io>

* functional picker

Signed-off-by: Kerry Archibald <kerrya@element.io>

* most style

Signed-off-by: Kerry Archibald <kerrya@element.io>

* nice style for options

Signed-off-by: Kerry Archibald <kerrya@element.io>

* get ShareType test passing

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add maplibre mock

Signed-off-by: Kerry Archibald <kerrya@element.io>

* lint and test

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add section to themes for location sharing cols

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add svg mock

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use same mock string as imageMock

Signed-off-by: Kerry Archibald <kerrya@element.io>

* newline

Signed-off-by: Kerry Archibald <kerrya@element.io>

* lint

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add live location icon

Signed-off-by: Kerry Archibald <kerrya@element.io>

* rename useEnabledShareTypes

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use solid color for live border

* use ternary

Signed-off-by: Kerry Archibald <kerrya@element.io>

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Kerry 2022-03-02 14:00:40 +01:00 committed by GitHub
parent 547144a565
commit b480bffab0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 354 additions and 298 deletions

View file

@ -17,15 +17,46 @@ limitations under the License.
import React from 'react';
import { mount } from 'enzyme';
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
import { MatrixClient } from 'matrix-js-sdk/src/client';
import { mocked } from 'jest-mock';
import { act } from 'react-dom/test-utils';
import '../../../skinned-sdk';
import LocationShareMenu from '../../../../src/components/views/location/LocationShareMenu';
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
import { ChevronFace } from '../../../../src/components/structures/ContextMenu';
import SettingsStore from '../../../../src/settings/SettingsStore';
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
import { LocationShareType } from '../../../../src/components/views/location/ShareType';
import { findByTestId } from '../../../test-utils';
jest.mock('../../../../src/components/views/messages/MLocationBody', () => ({
findMapStyleUrl: jest.fn().mockReturnValue('test'),
}));
jest.mock('../../../../src/settings/SettingsStore', () => ({
getValue: jest.fn(),
monitorSetting: jest.fn(),
}));
jest.mock('../../../../src/stores/OwnProfileStore', () => ({
OwnProfileStore: {
instance: {
displayName: 'Ernie',
getHttpAvatarUrl: jest.fn().mockReturnValue('image.com/img'),
},
},
}));
describe('<LocationShareMenu />', () => {
const userId = '@ernie:server.org';
const mockClient = {
on: jest.fn(),
removeListener: jest.fn(),
getUserId: jest.fn().mockReturnValue(userId),
getClientWellKnown: jest.fn().mockResolvedValue({
map_style_url: 'maps.com',
}),
};
const defaultProps = {
@ -36,7 +67,7 @@ describe('<LocationShareMenu />', () => {
onFinished: jest.fn(),
openMenu: jest.fn(),
roomId: '!room:server.org',
sender: { id: '@ernie:server.org' } as unknown as RoomMember,
sender: new RoomMember('!room:server.org', userId),
};
const getComponent = (props = {}) =>
mount(<LocationShareMenu {...defaultProps} {...props} />, {
@ -44,8 +75,43 @@ describe('<LocationShareMenu />', () => {
wrappingComponentProps: { value: mockClient },
});
it('renders', () => {
beforeEach(() => {
mocked(SettingsStore).getValue.mockImplementation(
(settingName) => settingName === "feature_location_share_pin_drop",
);
jest.spyOn(MatrixClientPeg, 'get').mockReturnValue(mockClient as unknown as MatrixClient);
});
const getShareTypeOption = (component, shareType: LocationShareType) =>
findByTestId(component, `share-location-option-${shareType}`);
it('renders location picker when only Own share type is enabled', () => {
mocked(SettingsStore).getValue.mockReturnValue(false);
const component = getComponent();
expect(component).toMatchSnapshot();
expect(component.find('ShareType').length).toBeFalsy();
expect(component.find('LocationPicker').length).toBeTruthy();
});
it('renders share type switch with own and pin drop options when enabled', () => {
// feature_location_share_pin_drop is set to enabled by default mocking
const component = getComponent();
expect(component.find('LocationPicker').length).toBeFalsy();
expect(getShareTypeOption(component, LocationShareType.Own).length).toBeTruthy();
expect(getShareTypeOption(component, LocationShareType.Pin).length).toBeTruthy();
});
it('selecting own location share type advances to location picker', () => {
// feature_location_share_pin_drop is set to enabled by default mocking
const component = getComponent();
act(() => {
getShareTypeOption(component, LocationShareType.Own).at(0).simulate('click');
});
component.setProps({});
expect(component.find('LocationPicker').length).toBeTruthy();
});
});

View file

@ -1,289 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<LocationShareMenu /> renders 1`] = `
<LocationShareMenu
menuPosition={
Object {
"chevronFace": "bottom",
"left": 1,
"top": 1,
}
}
onFinished={[MockFunction]}
openMenu={[MockFunction]}
roomId="!room:server.org"
sender={
Object {
"id": "@ernie:server.org",
}
}
>
<ContextMenu
chevronFace="bottom"
hasBackground={true}
left={1}
managed={false}
onFinished={[MockFunction]}
top={1}
>
<Portal
containerInfo={
<div
id="mx_ContextualMenu_Container"
>
<div
class="mx_ContextualMenu_wrapper"
style="top: 1px; left: 1px;"
>
<div
class="mx_ContextualMenu_background"
/>
<div
class="mx_ContextualMenu mx_ContextualMenu_withChevron_bottom"
>
<div
class="mx_ContextualMenu_chevron_bottom"
/>
<div
class="mx_LocationShareMenu"
>
<div
class="mx_LocationPicker"
>
<div
id="mx_LocationPicker_map"
/>
<div
class="mx_LocationPicker_error"
>
Failed to load map
</div>
<div
class="mx_LocationPicker_footer"
>
<form>
<div
class="mx_Dialog_buttons"
>
<button
class="mx_LocationPicker_cancelButton"
data-test-id="dialog-cancel-button"
type="button"
>
Cancel
</button>
<button
class="mx_Dialog_primary"
data-test-id="dialog-primary-button"
disabled=""
type="submit"
>
Share location
</button>
</div>
</form>
</div>
<div
class="mx_MLocationBody_marker"
id="mx_MLocationPicker_marker"
>
<div
class="mx_MLocationBody_markerBorder"
>
<span
class="mx_BaseAvatar"
role="presentation"
>
<span
aria-hidden="true"
class="mx_BaseAvatar_initial"
style="font-size: 17.55px; width: 27px; line-height: 27px;"
/>
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar_image"
src=""
style="width: 27px; height: 27px;"
/>
</span>
</div>
<div
class="mx_MLocationBody_pointer"
/>
</div>
</div>
</div>
</div>
</div>
</div>
}
>
<RovingTabIndexProvider
handleHomeEnd={true}
handleUpDown={true}
onKeyDown={[Function]}
>
<div
className="mx_ContextualMenu_wrapper"
onClick={[Function]}
onContextMenu={[Function]}
onKeyDown={[Function]}
style={
Object {
"left": 1,
"top": 1,
}
}
>
<div
className="mx_ContextualMenu_background"
onClick={[Function]}
onContextMenu={[Function]}
style={Object {}}
/>
<div
className="mx_ContextualMenu mx_ContextualMenu_withChevron_bottom"
style={Object {}}
>
<div
className="mx_ContextualMenu_chevron_bottom"
style={
Object {
"left": undefined,
}
}
/>
<div
className="mx_LocationShareMenu"
>
<LocationPicker
onChoose={[Function]}
onFinished={[MockFunction]}
sender={
Object {
"id": "@ernie:server.org",
}
}
>
<div
className="mx_LocationPicker"
>
<div
id="mx_LocationPicker_map"
/>
<div
className="mx_LocationPicker_error"
>
Failed to load map
</div>
<div
className="mx_LocationPicker_footer"
>
<form
onSubmit={[Function]}
>
<DialogButtons
cancelButtonClass="mx_LocationPicker_cancelButton"
disabled={false}
hasCancel={true}
onCancel={[MockFunction]}
onPrimaryButtonClick={[Function]}
primaryButton="Share location"
primaryDisabled={true}
primaryIsSubmit={true}
>
<div
className="mx_Dialog_buttons"
>
<button
className="mx_LocationPicker_cancelButton"
data-test-id="dialog-cancel-button"
disabled={false}
onClick={[Function]}
type="button"
>
Cancel
</button>
<button
className="mx_Dialog_primary"
data-test-id="dialog-primary-button"
disabled={true}
onClick={[Function]}
type="submit"
>
Share location
</button>
</div>
</DialogButtons>
</form>
</div>
<div
className="mx_MLocationBody_marker"
id="mx_MLocationPicker_marker"
>
<div
className="mx_MLocationBody_markerBorder"
>
<MemberAvatar
height={27}
member={
Object {
"id": "@ernie:server.org",
}
}
resizeMethod="crop"
viewUserOnClick={false}
width={27}
>
<BaseAvatar
height={27}
resizeMethod="crop"
width={27}
>
<span
className="mx_BaseAvatar"
role="presentation"
>
<span
aria-hidden="true"
className="mx_BaseAvatar_initial"
style={
Object {
"fontSize": "17.55px",
"lineHeight": "27px",
"width": "27px",
}
}
/>
<img
alt=""
aria-hidden="true"
className="mx_BaseAvatar_image"
onError={[Function]}
src=""
style={
Object {
"height": "27px",
"width": "27px",
}
}
/>
</span>
</BaseAvatar>
</MemberAvatar>
</div>
<div
className="mx_MLocationBody_pointer"
/>
</div>
</div>
</LocationPicker>
</div>
</div>
</div>
</RovingTabIndexProvider>
</Portal>
</ContextMenu>
</LocationShareMenu>
`;