-
-
Notifications
You must be signed in to change notification settings - Fork 9
Add support to customize UI components rendering #12
Changes from all commits
9061cc4
8b8ff2c
6559bfa
67e56d7
0da55bf
c9fe863
c645bb1
bfc3d1c
5f83dda
1611792
0d39f5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
Copyright 2023 Mikhail Aheichyk | ||
Copyright 2023 Nordeck IT + Consulting GmbH. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
/** | ||
* UI Component lifecycle events. | ||
*/ | ||
export enum UIComponentLifecycle { | ||
/** | ||
* An event to check if component should be shown by the Element. | ||
*/ | ||
ShouldShowComponent = "should_show_component", | ||
} | ||
|
||
/** | ||
* Opts object containing the result of whether the component should be shown or not. | ||
*/ | ||
export type ShouldShowUIComponentOps = { | ||
/** | ||
* Should be true to show the component, false to hide it. If not defined, then the default value from | ||
* the Element should be applied. | ||
*/ | ||
shouldShowComponent: boolean | undefined; | ||
}; | ||
|
||
/** | ||
* Listener for "should_show_component" request | ||
*/ | ||
export type ShouldShowUIComponentListener = ( | ||
shouldShowUIComponentOps: ShouldShowUIComponentOps, | ||
component: UIComponent, | ||
) => void; | ||
|
||
export enum UIComponent { | ||
/** | ||
* Components that lead to a user being invited. | ||
*/ | ||
InviteUsers = "UIComponent.sendInvites", | ||
|
||
/** | ||
* Components that lead to a room being created that aren't already | ||
* guarded by some other condition (ie: "only if you can edit this | ||
* space" is *not* guarded by this component, but "start DM" is). | ||
*/ | ||
CreateRooms = "UIComponent.roomCreation", | ||
|
||
/** | ||
* Components that lead to a Space being created that aren't already | ||
* guarded by some other condition (ie: "only if you can add subspaces" | ||
* is *not* guarded by this component, but "create new space" is). | ||
*/ | ||
CreateSpaces = "UIComponent.spaceCreation", | ||
Comment on lines
+48
to
+65
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe a more appropriate avenue for this kind of feature would be to piggy back off user permissions on a server as described in matrix-org/synapse#7731 I appreciate this issue has not received a lot of attention in recent times, but it seems like a more forward looking way to handle this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably could be used if implemented already, but it seems just and idea at the moment. But we would like some users (guests with special user ids) not to be able to invite, create rooms or spaces. Would be good to use a module API for that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is already possible using a feature flag There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
/** | ||
* Components that lead to the public room directory. | ||
*/ | ||
ExploreRooms = "UIComponent.exploreRooms", | ||
|
||
/** | ||
* Components that lead to the user being able to easily add widgets | ||
* and integrations to the room, such as from the room information card. | ||
*/ | ||
AddIntegrations = "UIComponent.addIntegrations", | ||
germain-gg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/** | ||
* Component that lead to the user being able to search, dial, explore rooms | ||
*/ | ||
FilterContainer = "UIComponent.filterContainer", | ||
|
||
/** | ||
* Components that lead the user to room options menu. | ||
*/ | ||
RoomOptionsMenu = "UIComponent.roomOptionsMenu", | ||
germain-gg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
Copyright 2023 Mikhail Aheichyk | ||
Copyright 2023 Nordeck IT + Consulting GmbH. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { | ||
UIComponentLifecycle, | ||
ShouldShowUIComponentOps, | ||
ShouldShowUIComponentListener, | ||
UIComponent, | ||
} from "../../src/lifecycles/UIComponentLifecycle"; | ||
import { RuntimeModule } from "../../src/RuntimeModule"; | ||
|
||
describe("UiComponentLifecycle", () => { | ||
let module: RuntimeModule; | ||
|
||
beforeAll(() => { | ||
module = new (class extends RuntimeModule { | ||
public constructor() { | ||
super(undefined as any); | ||
|
||
this.on(UIComponentLifecycle.ShouldShowComponent, this.shouldShowComponent); | ||
} | ||
|
||
protected shouldShowComponent: ShouldShowUIComponentListener = ( | ||
shouldShowUiComponentOps: ShouldShowUIComponentOps, | ||
component: UIComponent, | ||
) => { | ||
shouldShowUiComponentOps.shouldShowComponent = component !== UIComponent.CreateRooms; | ||
}; | ||
})(); | ||
}); | ||
|
||
it("should handle should_show_component request", () => { | ||
const opts: ShouldShowUIComponentOps = { shouldShowComponent: undefined }; | ||
|
||
module.emit(UIComponentLifecycle.ShouldShowComponent, opts, UIComponent.CreateRooms, "@user-id"); | ||
expect(opts.shouldShowComponent).toBe(false); | ||
|
||
module.emit(UIComponentLifecycle.ShouldShowComponent, opts, UIComponent.ExploreRooms, "@user-id"); | ||
expect(opts.shouldShowComponent).toBe(true); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seem to be a copy/paste of
UIFeature.ts
in thematrix-react-sdk
.Before considering this i'd want to explore ways to keep the two in sync. I'm actually unsure what value this brings over the existing possible customisations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is true, I have mentioned this in my first comment. Maybe a solution could be to change react-sdk to use a
UIComponent
from this PR? Or any other idea?Based on this matrix-org/matrix-react-sdk#9931 (comment) we may think that component visibility customization API is deprecated in favor of module API.
This solution would simplify our deployment, maybe quite a lot. We plan to put all visibility customizations and landing for guests in a separate module.