Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwiftUI Version of Room Notification Settings V2 #4670

Merged
merged 33 commits into from
Aug 18, 2021

Conversation

langleyd
Copy link
Member

@langleyd langleyd commented Aug 6, 2021

This PR introduces a SwiftUI implementation of Room Notification Settings V2

What's in this PR

  • SwiftUI Theme support
    • VectorContentModifier a SwiftUI modifier that can be used to apply any application level configuration at the top of the SwiftUI hierarchy.
    • VectorHostingViewController hosts a SwiftUI view and applies theming to any container NavigationController and applies the VectorContentModifier.
  • SwiftUI AvatarService
    • AvatarSize an enum to match the sizes in Design System. (Size naming TBD).
    • AvatarService a simple api that retrieves and caches avatars. Also a mock service.
    • VectorAvatarView a view for rendering avatars consistently by AvatarSize.
  • Implements Room Notification Settings
    • Shares the RoomNotificationSettingsViewModel with the UIKit implementation. This is generally a bit awkward with with the @available attribute. @available can't be used with stored properties for example. For the moment we plan on using SwiftUI for new features so won't face this problem in the general case. If we do find more areas we are trying to support both UIKit + SwiftUI and avoid code duplication we may want to look into this further.
    • Originally implemented the feature using SwiftUI List component which is backed by UITableView. List does not give you access to style all parts of the tableview like the background, nor does it give you a reference to the underlying UITableVIew. To implement the avatar header for example I would have had to put the header inside a Section with no content in order to get the grouped UITableView to style correctly. Rather than fighting it I decided to use a VStack which gives you full control but you have to do a bit more of the styling yourself. You can mitigate this by creating your own styles. I think in future this is probably give us more re-use and better flexibility.
    • Using mocked dependencies in our ViewModel (previously done to make view models more testable and decoupled) had the nice side-effect that we can always run our live preview without a network connection/MxSession.

Update 2021-9-17:

  • Added an AvatarViewModel owned by the AvatarView via a @StateObject so that only mxContentUri is needed as input to the view.
  • To do this dependency management was added via DependencyContainer and the EnvironmentKey DependencyContainerKey
  • Inject property wrapper, Injectable protocol and InjectableObject were also added to remove some boilerplate.
  • To simplify things further I removed the dependency on AvatarGenerator and we just render that part in SwiftUI.

Screenshots

Todos

  • Disable BuildSetting
  • Remove Podfile changes
  • Fix live theme updating.
  • Fix padding below avatar
  • Use private on navigation buttons in RoomNotificationSettingsView
  • Fix avatar service not returning generated image on network error
  • Add progress spinner during save.
  • Clear warnings for Clear easy Xcode warnings in Modules #4677
  • Add Dependency Management and AvatarViewModel
  • Do avatar placeholder rendering in SwiftUI rather then AvatarGenerator

resolves #4669

@langleyd langleyd marked this pull request as draft August 6, 2021 09:08
@langleyd langleyd marked this pull request as ready for review August 12, 2021 12:52
@pixlwave
Copy link
Member

This looks really great! So good how much the VStack looks and feels like a List 😄. Sorry I added quite so many comments. I think it would be nice to have a few more doc comments (autocompletion hints for the new view types would be super helpful going forward).

Two general points I'm wondering about that are worth discussing tomorrow:

  • Should we have a naming convention to distinguish SwiftUI views from UIViews? For example following the base names like VectorForm, VectorAvatarImage and FormSectionFooterText?
  • It might be worth making our view text properties let text: LocalizedStringKey to work with SwiftUI's i18n features down the road - genuinely no idea if that would ever be useful or if it would impact in any way right now.

@langleyd
Copy link
Member Author

+1 @pixlwave regarding naming. Also something I'd like to discuss. Also things like DesignKit and what ends up going in there. Main reason I had VectorAvatarImage was because there was already an AvatarView in out UIKit code. But yea would be good to discuss good practices/conventions in this regard. And thanks for the comments, keep them coming! 😄

I think if we start using LocalizedStringKey it will look for strings in resources with that key which wont work with the current SwiftGen approach (Isn't using english as the key). But yea probably a few SwiftUI features like that we can discuss.

@pixlwave
Copy link
Member

Updates look good to me. Wondering if it should be VectorHostingController to match UIHostingController now I've seen it written in Manu's comment above?

…thub.com:vector-im/element-ios into langleyd/4669_room_notification_settings_swiftui
@langleyd
Copy link
Member Author

👀 at build errors

@langleyd
Copy link
Member Author

Ok looks like build is fixed, test and alpha failed due to timeouts.

@github-actions
Copy link

github-actions bot commented Aug 17, 2021

📱 Scan the QR code below to install the build for this PR.
🔒 This build is for internal testing purpose. Only devices listed in the ad-hoc provisioning profile can install Element Alpha.

QR code

If you can't scan the QR code you can install the build via this link: https://i.diawi.com/VeWcc3

Copy link
Member

@manuroe manuroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This injection module is very nice!

I wonder if we should separate pure SwiftUI code and UIKit code right now. I am afraid that we will mix or miss things if we continue to put everything into Modules. The RoomNotificationSettings code is hybrid and can stay there but pure SwiftUI code should not be not mixed with UIKit.

Options:

  • keep current Modules and SwiftUIModules folders as the same level
  • add another layer like Modules/UIKit with current code and Modules/SwiftUI
  • or ...

Copy link
Member

@pixlwave pixlwave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, especially the dependency injection stuff! More thoughts on naming 🙄

  • Injectable vs InjectableObject are very close in meaning. When I see Injectable by itself, it's hard to reason about whether it's to be injected or can receive injections. But I'm struggling to think of something better so might simply be something to learn.
  • I was clearly wrong suggesting never using View suffix at all. I think it still makes sense for reusable components, but RoomNotificationSettingsView was probably clearer for the entire composition? 😕

@langleyd
Copy link
Member Author

@pixlwave and I went over apple usage and seems they use View when removing it would cause confusion, so will go with that as a rule of thumb for the moment.

@pixlwave I had the exact same thoughts regarding Injectable. I will review some other DI tooling and find a better match. Will update in a separate PR i think when I iterate on this stuff a bit.

Copy link
Member

@pixlwave pixlwave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All looks good from my perspective. That switch on the view model is wayyyy cleaner to read too 😄

@langleyd langleyd merged commit d81f4ad into develop Aug 18, 2021
@langleyd langleyd deleted the langleyd/4669_room_notification_settings_swiftui branch August 18, 2021 16:51
@pixlwave pixlwave mentioned this pull request Aug 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SwiftUI version of Room Notification Settings V2
3 participants