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

Refactoring menu building flow #88

Merged

Conversation

Garfeild
Copy link
Contributor

@Garfeild Garfeild commented Oct 30, 2023

This PR contains set of changes to simplify how Menu is built:

  • populate() function is split into several case specific functions.
  • Android and iOS specific submenu enum types are replaced with more flexible combination of protocol and structs. This allows to unify logic of submenu building.
  • Pre-population code is updated to have separate logic of creating main menu actions and platform headers.

Overall refactored Menu should be more flexible for future changes, e.g. adding new actions to device sub menu.

Copy link
Owner

@okwasniewski okwasniewski left a comment

Choose a reason for hiding this comment

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

This looks very good! I will do some more testing later this week, here are some initial comments I've found

MiniSim/Menu.swift Outdated Show resolved Hide resolved
MiniSim/AppleScript Commands/ExecuteCommand.swift Outdated Show resolved Hide resolved
MiniSim/AppleScript Commands/ExecuteCommand.swift Outdated Show resolved Hide resolved
MiniSim/AppleScript Commands/ExecuteCommand.swift Outdated Show resolved Hide resolved
MiniSim/MenuItems/SubMenuItem.swift Show resolved Hide resolved
MiniSim/MiniSim.swift Outdated Show resolved Hide resolved
MiniSim/MiniSim.swift Outdated Show resolved Hide resolved
MiniSim/Menu.swift Outdated Show resolved Hide resolved
MiniSim/Menu.swift Outdated Show resolved Hide resolved
MiniSim/Menu.swift Outdated Show resolved Hide resolved
* populate() is split into smaller functions to handle different parts
  of the logic:
  - filter function returns list of devices for particular platform
  - createMenuItem create new menu item for device
* SubMenuItem protocol is introduced to provide generic type for
  submenus
* Android and iOS submenu types are updated to conform to new protocol
* NSMenuItem extension is added to provide convinience init for sub menu
  items as well as custom command menu items
* Menu is updated to use new types and better building flow
* MenuSections is replaced with MainMenuActions and DeviceListSection
  types
* MainMenuActions covers general actions like openings settings or
  quiting app
* DeviceListSection is responsible for platform section headers
* Android and iOS specific sub menu types are removed
* New system with structs instead of enum values is added
MiniSim/Menu.swift Outdated Show resolved Hide resolved
MiniSim/MenuItems/SubMenuItem.swift Outdated Show resolved Hide resolved
MiniSim/Menu.swift Outdated Show resolved Hide resolved
@Garfeild Garfeild requested a review from okwasniewski November 2, 2023 14:47
MiniSim/Menu.swift Outdated Show resolved Hide resolved
@Garfeild Garfeild force-pushed the feat/refactoring-device-menu branch from a1a287c to 3556fec Compare November 2, 2023 18:44
@Garfeild Garfeild requested a review from okwasniewski November 2, 2023 20:11
@okwasniewski
Copy link
Owner

Looks like something is wrong with the divider appearing after first 3 items

CleanShot 2023-11-03 at 10 04 18@2x

menuItem.target = self
menuItem.action = #selector(IOSSubMenuClick)
subMenu.addItem(menuItem)
self.safeInsertItem(menuItem, at: startIndex + index + 1)
Copy link
Owner

Choose a reason for hiding this comment

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

This logic needs to be aligned to account for the separator.

You can change it like so (If you won't find better solution):

self.safeInsertItem(menuItem, at: section == .iOS ? startIndex + 1 : startIndex + index + 1)

@Garfeild
Copy link
Contributor Author

Garfeild commented Nov 3, 2023

Very strange. Could you give me steps to reproduce?

@okwasniewski
Copy link
Owner

okwasniewski commented Nov 4, 2023

If you have more than 3 simulators that's constantly happening. I've checked also on my second Macbook and it's the same. It happens on the initial launch of the app and if you later on add new simulator through Xcode same thing happens.

What you could do is always insert new items at the top of the list:

self.safeInsertItem(menuItem, at: startIndex + 1)

@Garfeild
Copy link
Contributor Author

Garfeild commented Nov 4, 2023

Not sure why, but I haven't experienced such behavior. What macOS version do you run? Regarding your suggestion. It will work, but it's not ideal since order will be different at restart of the app. What if we completely rebuild section by removing all items between header and separator?

guard let header = self.items.first(where: { $0.tag == section.rawValue }),
      let startIndex = self.items.firstIndex(of: header),
      let lastIndex = self.items[startIndex..<self.items.count].firstIndex(where: { $0.isSeparatorItem }) else {
    return
}

if startIndex != lastIndex-1 {
    self.items[startIndex+1..<lastIndex]
        .forEach { self.safeRemoveItem($0)}
}

items.forEach { self.safeInsertItem($0, at: startIndex + 1) }

@okwasniewski
Copy link
Owner

@Garfeild Im running latest MacOS 14.0. Why items will order will be different after restart? Rebuling sections after every open of the menu doesn't sound too efficent. We can always reverse the items array and append them at the top like so:

for menuItem in items.reversed() {
            if let itemIndex = self.items.firstIndex(where: { $0.title == menuItem.title }) {
                self.replaceMenuItem(at: itemIndex, with: menuItem)
                continue
            }
            self.safeInsertItem(menuItem, at: startIndex + 1)
        }

It was working reliably for me without any issues.

@Garfeild
Copy link
Contributor Author

Garfeild commented Nov 5, 2023

The order is alphabetical, right? If you add sim that doesn't match order, it will be on top. Once you restart app, it will be placed properly.

Screen.Recording.2023-11-05.at.21.32.00.mov

Another question, do you see the same behavior of incorrectly located separator in commit 5ebe102?

@okwasniewski
Copy link
Owner

I'm fine with the behaviour you showed that it's not alphabetical when you insert new item - it isn't the most important thing 👍🏻

And yeah it's the same on 5ebe102
CleanShot 2023-11-06 at 09 12 35@2x

@Garfeild
Copy link
Contributor Author

Garfeild commented Nov 6, 2023

Alright, I will look into that afterwards 😉 I would like to insert item into right place for very beginning. And I'm kinda concerned about current way of managing sections.

@okwasniewski
Copy link
Owner

Sure let's merge it to unblock others and I will also take a look at inserting items 👍🏻

Copy link
Owner

@okwasniewski okwasniewski left a comment

Choose a reason for hiding this comment

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

Thanks for huge amount of great work! 🎉

@okwasniewski okwasniewski merged commit d925c57 into okwasniewski:main Nov 6, 2023
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.

2 participants