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

Allow option to remain on v2 branch when checking for updates [enhancement] #962

Open
stevenya97 opened this issue May 19, 2024 · 4 comments

Comments

@stevenya97
Copy link

Description

With the new v2.2.4 update, it seems currently v2.2.3 is stuck with only upgrading to v3 via the 'check for update' modal. Would be great if there was a setting/change to include/exclude major version upgrades. i.e. v2.2.4 can smoothly update to v2.2.5 without needing to visit the github repo.

Rationale

Only way to get the new v2.2.4 update it seems is to visit the github repo. Some apps have the option to select between checking for 'all versions/branches' and the 'current branch'. This makes sure that any important updates are still delivered to users regardless of which version. I imagine the percentage of users who regularly check the repo releases page compared to overall users is not as high.

Additional info

Thanks again for keeping v2 updated with the launch of v3!

@noah-nuebling
Copy link
Owner

noah-nuebling commented May 20, 2024

Hey @stevenya97, thanks for the feedback!

I definitely agree that this is a usability issue.

I've been thinking and researching a bit on how to solve this. I think, simply adding a toggle into the app that says "Update to Mac Mouse Fix 3 and above" would be fine, but I thought maybe I could do it in a different way. In the following text I'm just sort of explaining / exploring these ideas. It might be a bit much, but in case you're interested to read it, I'd be glad to hear any feedback on it!


So let's say we're a user of Mac Mouse Fix, and we're on version 2.1. Let's say the latest 2.x version is 2.4, and let's say the latest available version overall is 3.3.

-> So now we have an example scenario which we can use to explore the concepts.

We call the leftmost part of the version number the major version. So since we're currently on 2.1, we're currently on major version 2. Since the latest available version overall is 3.3, the latest available major version is 3.

When the app checks for new updates, it uses certain logic to decide which update (if any) to present to the user. Let's call this logic the 'updating logic'.

-> Now we have a the terminology to explore the concepts.

The current 'updating logic' of the app is very simple. It simply checks for the latest available version of the app. If the latest available version is newer than the current version that the user is using, then the app will prompt the user to update to this latest version.
So in our scenario, where we're using version 2.1, the app would simply prompt you to update to 3.3, because that's the latest available version overall, and it's newer than the current version 2.1.

The problems with this simple updating logic are:

  1. Problem: If there's a newer major version available than the major version the user is currently using (E.g. the user is on 2.x and there's a 3.x update available), then the user will never be prompted to update to the latest version of the current major version. So for example, if we're on 2.1, and 3.3 is available, then we will never be prompted to update to version 2.4. This is a problem, if the user wants to avoid updating to the next major version, but wants to stay up-to-date on the current major version. (This is likely the case for many Mac Mouse Fix 2 users, since they would like to keep using Mac Mouse Fix 2 without paying for Mac Mouse Fix 3)
  2. Problem: If the user updates to a new major version, they might not see the most important patch notes. For example if the user is on 2.1 and is prompted to update to 3.3, they will only see the patch notes for 3.3, but they won't see the patch notes for 3.0, which likely introduced major changes that the user might want to know about. Recently, this kind of issue has lead to several people updating to MMF 3 without being aware of the pricing changes, and they ended up being surprised and upset when the app stopped working and prompted them to pay $3 all of a sudden.

So to address these issues, (without introducing any new toggles in the UI - not totally sure if that's the best priority to have here), I thought we could do the following:

  1. Idea: Make the app prioritize updates that stay on the current major version. So if you're currently on version 2.1, and the latest 2.x version is 2.4, and the latest version overall is 3.3, then the app will first prompt you to update from 2.1 -> 2.4, instead of immediately prompting you to update to latest version (3.3). Only if there's no 2.x version to upgrade to (Either because you're already on the latest 2.x version, or because you skipped the latest 2.x version), then the app will prompt you to update to a 3.x version. With this logic you could also skip any 3.x versions you're prompted to upgrade to, but then still be prompted to update to the latest 2.x version.
    • Would this solve your problem @stevenya97? If you're on 2.x, you'd still be prompted to update every time a new 3.x, release comes out, but you could just skip them all and still receive the latest 2.x update.
  2. Idea: We could also make it so that you're only ever prompted to update to the inital release of a new major version. So for example, if you're on 2.4, you would only be prompted to update to 3.0 (which is the initial release of major version 3). You would never be prompted to jump from 2.4 right to 3.3 (Which - in our scenario - is the latest version overall)
    • This would make it so anyone updating to version 3.x would first see the 3.0 release notes. That way it would be very transparent to users, what major changes were introduced in 3.0.
      (There might be better ways to get people who update to version 3.x to see the 3.0 release notes. However, in my experience, this needs to be very prominent. For example the very first text in the MMF 3.0.1 and 3.0.2 release notes, was a link to the 3.0.0 release notes. But still, several people were unaware about the pricing changes, and ended up having a negative experience.)

The problem with these changes is that it would be somewhat inefficient and cumbersome to people who want to update to the newest version immediately. If we implemented both of the discussed ideas, then someone on version 2.1 who wants to get the latest version (3.3), would first update from 2.1 -> 2.4 (the latest 2.x version), then they would update from 2.4 -> 3.0 (the initial release of major version 3), and then finally, they would update from 3.0 -> 3.3 (the latest version of the app overall.)

So in the worst case, that would be 3 instances of downloading a copy of Mac Mouse Fix, just to get the 1 copy that the user actually wants to use - the latest version (3.3).

However, that's just the worst case scenario, which wouldn't happen often. (Only in some cases when updating to a new major version) And the upside is that the updating process would be more flexible and transparent to the user, without adding any extra toggles in the UI.


... hmm now that I think about it. I think these 2 ideas that I described here shouldn't really be applied to all major version changes.

I think we could summarize that these two ideas we described above make the updating process more cumbersome in favor of allowing the user to flexibly avoid the next major version (while keeping their current major version up-to-date) and while making it more transparent to the user what changes the next major version brings.

I think this is only really useful to the user, if the new major version has some major downside/caveat. For example, this behaviour would have been appropriate for the change from MMF 2 to MMF 3, because MMF 3 is a paid update - that's a major caveat for users that they probably want to be aware of and possibly want to avoid.

But for non-paid updates (even if it's a new major version), the update is usually kind of a no-brainer, because the app generally gets better, and there's generally no downside to updating.

But I think if we implemented the 2 ideas described above for any paid updates of Mac Mouse Fix, that would make sense, and be a pretty nice user experience I think.

The thing is just that I don't know if there will be any paid updates after MMF 3. I don't plan to have any more paid updates and I'll try to avoid it if it's financially feasible - which I think it will be. So I'm not sure if it's worth spending much time trying to implement this stuff just for Mac Mouse Fix 2.2.5?
... But I'll think about it.

@stevenya97
Copy link
Author

Thanks for the breakdown and insights! Lots of meaningful tidbits and many possible routes. Definitely a balance between flexibility and ease of use. I'm not too familiar with your codebase yet so I can only offer some opinions.

Idea: Make the app prioritize updates that stay on the current major version. So if you're currently on version 2.1, and the latest 2.x version is 2.4, and the latest version overall is 3.3, then the app will first prompt you to update from 2.1 -> 2.4, instead of immediately prompting you to update to latest version (3.3). Only if there's no 2.x version to upgrade to (Either because you're already on the latest 2.x version, or because you skipped the latest 2.x version), then the app will prompt you to update to a 3.x version. With this logic you could also skip any 3.x versions you're prompted to upgrade to, but then still be prompted to update to the latest 2.x version.

This behavior without adding any more toggles does seem to cover the issue. This follows semantic versioning and logically makes sense that 2.x versions should always update to the latest major 2.x version. Overall I think that's the general flow that I would have suggested as well. Making sure MMF2 users get all their updates while still offering MMF3 as a choice seems like to way to go. I do get that changing too much for MMF2 might not be worth it at this time. I agree that generally updating to the latest current major version has very little downside.

I haven't looked through the entire repo yet but what does the update logic look like? Might be a way of structuring things so that you can leave MMF2 as is while still offering a better UX for paid users. Is the latest version retrieved from a server with the app analyzing the response? If updating is done say via a shared manifest, perhaps separating out MMF2 and MMF3 is the way forward?

Screenshot 2024-05-20 at 7 01 47 PM
For the release notes, certainly a tricky thing to tackle with so many changes between versions. Adding a link to view all releases/changes since 3.0 could be helpful, but this would be another entity to maintain unless you would be able to do it inline instead of a link. For 2.x users, currently the update modal shows the notes for 3.0.2 which does contain info on the pricing changes but I know it can maybe be easy to miss. Instead of a configurable toggle, maybe offer a set of 3 buttons: 'Skip This Version', 'Install Update', and 'Upgrade to 3'. My thinking is that using the term "upgrade' suggests a paid path and avoids confusion.

In terms of future paid upgrades, as a dev I'm all for it if there is a good reason for doing so. Looking at the popular Mac app Bartender, they seem to do a new paid version every couple of macOS versions, usually in line with a system api change that requires a major rewrite or a new feature that requires targeting the new macOS SDK, which is understandable. I think they do upgrade pricing as well for people already owning a paid license. I believe MMF 3 had a similar trajectory due to underlying api changes to mouse input? As long as the old version is still supported, I think people would be kind to it.

Thanks for listening to me ramble alongside you haha. Love the functionality your app offers!

@noah-nuebling
Copy link
Owner

noah-nuebling commented May 21, 2024

Hey there, thanks for your insights and perspective!

I haven't looked through the entire repo yet but what does the update logic look like? Might be a way of structuring things so that you can leave MMF2 as is while still offering a better UX for paid users. Is the latest version retrieved from a server with the app analyzing the response? If updating is done say via a shared manifest, perhaps separating out MMF2 and MMF3 is the way forward?

Since version 2.0.0, the app uses the Sparkle udpating framework for updates. There is a branch of this repo called update-feed which contains autogenerated rss feeds (I think they are rss feeds?) which describe all the versions of MMF (alongside update notes and some meta information) in a way that the Sparkle updating framework can understand.

When the app starts up, it downloads this rss feed and then the Sparkle framework searches the rss feed for any updates that it might want to present to the user.

Currently there are two different 'appcasts'. One for only stable versions, and one for all versions, including prereleases.

It would have probably been feasible and useful to create a new set of appcasts for MMF 3. That way we could freely control, which updates MMF 2 users see vs which updates MMF 3 users see. However, since MMF 3 is already released for a few months, I don't think it's easy to adopt something like this for MMF 3 at this point. But I'm not sure.

while still offering a better UX for paid users

Do you have anything specific in mind about how you would change the UX for paid users vs free users?

For the release notes, certainly a tricky thing to tackle with so many changes between versions. Adding a link to view all releases/changes since 3.0 could be helpful, but this would be another entity to maintain unless you would be able to do it inline instead of a link.

We could probably autogenerate a scrolling list of all update notes, and show that in the update window. This would surely be a nice UX, and I don't think it would be too hard to maintain.

But I don't think this solves one of the core issues I was trying to address: The (original iteration) of the 3.0.1 and 3.0.2 update notes already contained pretty prominent links to the 3.0.0 update notes. But still, many people ended up being surprised and upset about the changes in MMF 3.0.0 (specifically the monetization). I think it would be best if users could read "MMF 3+ is no longer free" right when the update window appears. It should be really hard to miss. If they have to click a link or scroll down, I think it might already be too hard to miss.

For 2.x users, currently the update modal shows the notes for 3.0.2 which does contain info on the pricing changes but I know it can maybe be easy to miss.

I added this info recently, as a response to several people being confused. Originally, there was just a link to the 3.0.0 update notes, and many people were confused. I think the info as it's presented now might be clear enough, but I haven't received any feedback on it. Also theoretically, for every new version of MMF I release, there could always be someone who is updating from MMF 2, so I feel like I would always have to include these notes on the pricing changes at the top for all update notes, to do right by MMF 2 users.

It would be better, to either build some extra logic into the update notes, so that only MMF 2 users get an extra warning about the pricing changes the top of the update notes. However, I've only enabled javascript for the update notes with 2.2.4, and javascript would be necessary to implement something like this.

Alternatively, we could always have users update to the first version of a new major release. So if you're on 2.2.1, the app would present you with the 3.0.0 update, instead of immediately showing you the 3.0.2 update. This way, only the 3.0.0 update needs to contain info about the pricing changes, and everyone updating from MMF 2 would see those 3.0.0 update notes.

In terms of future paid upgrades, as a dev I'm all for it if there is a good reason for doing so. Looking at the popular Mac app Bartender, they seem to do a new paid version every couple of macOS versions, usually in line with a system api change that requires a major rewrite or a new feature that requires targeting the new macOS SDK, which is understandable. I think they do upgrade pricing as well for people already owning a paid license. I believe MMF 3 had a similar trajectory due to underlying api changes to mouse input? As long as the old version is still supported, I think people would be kind to it.

Thanks for your perspective. I definitely prefer the user experience of lifetime licenses. So far it seems like this will be financially viable. But if it's not financially viable anymore, then I think I might adopt a similar system to Bartender, where some major updates are paid updates. It seems like the most user friendly way to get some recurring revenue from existing users.

Thanks for listening to me ramble alongside you haha. Love the functionality your app offers!

I'm glad you like the app! :) And thanks for your feedback. It has definitely helped me think about this problem. Yesterday I even tried to implement a solution based on our ramblings:

@noah-nuebling
Copy link
Owner

noah-nuebling commented May 21, 2024

Solution Implementation

Yesterday I spent some time to implement new custom logic for choosing which update to present to the user in the version-2 branch. The behavior is similar, but a little different from the 2 'ideas' I described in the original comment. The logic is currently as follows:

  • 1: We have a custom implementation for skipping versions. When the user skips a major update, they will never be presented with another major update, so they will stay on the current major version. But when the user skips a minor update x, the user will still be notified of subsequent minor updates.
  • 2: When jumping to a new major version - we update to the initial release of that major version. So e.g. if we're currently on MMF 1.0.4, it will update us to 2.0.0 instead of going straight to 2.2.3. That's so the user sees all the update notes for the initial release of each major version - since those update notes might contain important info.
  • 3: We don't jump over major versions. So e.g. if we are on 0.9, we update to 1.0 instead of going straight to 2.0. That's also so the user sees the major version's update notes - in case they contain important changes. (Not totally sure if this rule is overkill. But let's say the user updates from MMF 2 directly to MMF 4, and the MMF 4 release notes don't re-explain that MMF 3 and later are paid - that might lead to confusion.)
  • 4: If none of the other points apply, choose the latest version

Note that none of these points covers the idea I described in the original comment where we would always prioritize free updates. I don't think implementing this behaviour is necessary, since the user can simply opt out of any major version updates, and instead keep receiving minor patches instead. And since all paid updates are also major updates, this should cover the same usecase.

(All paid updates are also major updates, but not all major updates are also paid updates.)


So how this logic would play out in practise is the following:

Let's say we applied this logic to all currently published versions of Mac Mouse Fix.
And then let's say you start on Mac Mouse Fix 0.9. (Which was the first published version of MMF)

After opening MMF 0.9, it will present you with the 1.0.0 update. If you accept, the app will restart and MMF 1.0.0 will open up. After opening, it will immediately present you with the 2.0.0 update. If you accept and restart, the app will then present you with the 3.0.0 update (with the update notes prominently stating that MMF 3 is no longer free, but you can keep using MMF 2).

Then, let's say you decide that you want to stay on the free version (MMF 2), and therefore you skip the 3.0.0 update. Then, immediately after that, the app will prompt you to update to version 2.2.4 instead - the latest minor update to MMF 2.

Then, in the future, if MMF 2.2.5 releases, you will be prompted to update to 2.2.5. You could then skip 2.2.5, but you'd be prompted to update again, once 2.2.6 releases. However, you wouldn't ever be prompted to update to any new major version of the app like MMF 3.0.0 or MMF 4.0.0 etc.

That's because, when you skipped the update to the next major version (in this case MMF 3) the intent of that is understood as "I want to stay on the current major version - MMF 2".

You can also reset your skipped versions, by turning automatic updates off and on again.


Here's a screen recording to demonstrate how it would look in a common scenario:

Screen.Recording.2024-05-21.at.11.12.17.mov

If you have any feedback on this, please let me know! Do you think you would like using the system? Any problems you could think of?

If this is too much, please just ignore this, I also totally understand that!

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

No branches or pull requests

2 participants