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

Customizable drawer #3199

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

DavidEdwards
Copy link
Collaborator

@DavidEdwards DavidEdwards commented Jan 21, 2023

Add all options from customizing the Tabs to a new system from customizing the side drawer. This allows us to resolve requests such as #3010.

out.mp4

@DavidEdwards DavidEdwards mentioned this pull request Jan 24, 2023
3 tasks
@connyduck
Copy link
Collaborator

I think this would be a nice addition, if you clean this PR up I'll review it!

@DavidEdwards
Copy link
Collaborator Author

Absolutely. Now the other is merged into develop, this one can be rebased and made cleaner.

I'll look into that soon.

@DavidEdwards DavidEdwards force-pushed the customizable-drawer branch 2 times, most recently from 1746333 to 86a4bae Compare February 15, 2023 20:11
@DavidEdwards
Copy link
Collaborator Author

@connyduck It should be runnable / testable / reviewable now. It is synced with develop.

I am leaving it on draft, as I am positive changes will need to be made.

Copy link
Collaborator

@connyduck connyduck left a comment

Choose a reason for hiding this comment

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

I think we should not have a special section in the drawer that can be customized, rather make everything above Account prefs/prefs/About customizable. We may need to have some items that can only be added to the drawer and not as tab, but most items should make sense as both.

… allow us to be more generic in centralizing how tab data can be displayed. Drawer preferences added to the account entity, defaults are Trending and Federated. Replaced the core code for the TabPreferenceActivity with a more generic OrderableListPreferenceActivity. Allowing us to share the code for creating lists of tab data. The side drawer includes a subsection populated from the account drawer preferences.

Custom Drawer: Update with changes from develop. Changes requested from review. TabData changed to allow different kinds of actions. This allows us to launch activities as well as using fragments. Add functionality for the new sidebar items. Only allow intent based actions from the sidebar.
@DavidEdwards
Copy link
Collaborator Author

@connyduck It should be in a good state now. Have a look when you have the time.

I just noticed the issue here too: #3331

@nikclayton You might want to have a look what you think too.

@nikclayton
Copy link
Contributor

Will do, after I've wrapped up #3436

Copy link
Collaborator

@connyduck connyduck left a comment

Choose a reason for hiding this comment

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

I love this, really cool feature 😍


@Parcelize
data class TabData(
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should definitely have a different name now, how about "AppScreen" or "ScreenData"?

Copy link
Collaborator

Choose a reason for hiding this comment

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

And I wonder if two classes would model things better here.
In the end, all screens can be shown in their own Activity, and some can also be shown as Tabs. So maybe like this

open class ScreenData(
    val id: String,
    @StringRes val text: Int,
    val icon: Icon,
    val arguments: List<String> = emptyList(),
    val intentAction: (Context, List<String>, Boolean) -> Intent,
    val title: (Context) -> String = { context -> context.getString(text) },
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as ScreenData

        if (id != other.id) return false
        if (arguments != other.arguments) return false

        return true
    }

    override fun hashCode(): Int {
        var result = id.hashCode()
        result = 31 * result + arguments.hashCode()
        return result
    }

    open fun withArguments(args: List<String>): ScreenData = ScreenData(
        id = id,
        text = text,
        icon = icon,
        arguments = args,
        intentAction = intentAction,
        title = title
    )
}


class TabScreenData(
    id: String,
    text: Int,
    icon: Icon,
    arguments: List<String> = emptyList(),
    val fragmentAction: (List<String>) -> Fragment,
    title: (Context) -> String = { context -> context.getString(text) },
) : ScreenData (
    id = id,
    text = text,
    icon = icon,
    arguments = arguments,
    intentAction = { context, tabData, accountLocked -> TabActivity.getIntent(context, id, accountLocked) },
    title = title
) {
    override fun withArguments(args: List<String>) = TabScreenData(
        id = id,
        text = text,
        icon = icon,
        arguments = args,
        fragmentAction = fragmentAction,
        title = title
    )
}

then have one createTabScreenDataFromId(...): TabScreenData and a createScreenDataFromId(...): ScreenData that calls the former, instead of AllowedContext check for the class, use intentAction whenever you need an intent, fragmentAction for Fragments, etc...

(But is works now and isn't super bad, better leave it if it is too complicated)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Definitely, I like the idea of ScreenData. TabData really makes no sense any more in the given context. I'll see how easy the change to inheritance is.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It took a bit to refactor it. There are a lot of files touched by this. I think it is better in the long run.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@connyduck Alright, the latest code changes should represent what you asked for.

@nikclayton
Copy link
Contributor

Just looking at the UX, I haven't looked at the code yet. I'm coming at this from the assumption that the goal in #3331 is good.

First impressions:

  • Federated timeline can probably be put back on the list of default tabs
  • Navigation menu doesn't show all destinations by default:
    • Notifications
    • Local timeline
    • Direct messages / conversations
  • There's still a limit of 5 tabs
  • Unclear why there's a limit of 10 entries in the navigation drawer
  • Unclear why some things can appear in the navigation drawer and tabs (e.g., notifications) and some things are drawer only (e.g., scheduled posts).

And I think the interaction model is still backwards. The user has to think about where the are first (navigation drawer or tabs), and what they want to see there second.

But I think it should be the other way around -- the user creates / selects and configures the timelines that they want to see, and then controls where those timelines are placed.

Nowithstanding that, I also noticed an odd gap (with a divider) in the navigation menu between the bottom of the account info and the "Edit profile" menu entry, see screenshot:

@DavidEdwards
Copy link
Collaborator Author

First impressions:

Federated timeline can probably be put back on the list of default tabs
Navigation menu doesn't show all destinations by default:
Notifications
Local timeline
Direct messages / conversations

I tried to leave the list as it was. I think I only added federated and trending as defaults. Though this would be easy to change.

There's still a limit of 5 tabs

I would prefer not to get involved in that for this PR. That could always come afterwards.

Unclear why there's a limit of 10 entries in the navigation drawer

Yes, that is a good question. I am not sure why there's a limit. It is probably because I copied the code over and just edited it larger. We could certainly remove the limit.

Unclear why some things can appear in the navigation drawer and tabs (e.g., notifications) and some things are drawer only (e.g., scheduled posts).

It is a technical limitation. Some systems are activities and some are fragments. If the system uses an activity, I would have to refactor it to use a fragment. That is far too complicated. The downside is that some systems can only be accessed through intents.

And I think the interaction model is still backwards. The user has to think about where the are first (navigation drawer or tabs), >and what they want to see there second.

But I think it should be the other way around -- the user creates / selects and configures the timelines that they want to see, and then controls where those timelines are placed.

That is a much bigger question. I'm not sure I can answer it.

Nowithstanding that, I also noticed an odd gap (with a divider) in the navigation menu between the bottom of the account info and the "Edit profile" menu entry, see screenshot:

Good spot. I have removed it.

@DavidEdwards
Copy link
Collaborator Author

To do: clicking a notification doesn't open notifications if it isn't on the tabs. It should also support the sidebar.

@nikclayton
Copy link
Contributor

Still working on the 22 release, and the other arch changes, so a quick drive-by comment:

It is a technical limitation. Some systems are activities and some are fragments. If the system uses an activity, I would have to refactor it to use a fragment. That is far too complicated. The downside is that some systems can only be accessed through intents

Maybe it would be easier to tackle refactoring the existing activities that don't have fragments, and turn them in to an activity+fragment combo before going further with this work?

That is a much bigger question. I'm not sure I can answer it.

So maybe we can also get group consensus on the ideas in #3331 first? Once we've got consensus on a direction we can go from there. ?

@connyduck connyduck self-assigned this Jul 25, 2023
@DavidEdwards
Copy link
Collaborator Author

@connyduck What should we do with this? It is assigned to you for architecture?

I would be OK with rebasing this onto the current develop branch, if there is hope of resurrecting its' cold dead corpse. 🧟

@connyduck
Copy link
Collaborator

Yes I know I said I'll check the code, but then things happened, sorry for that.

I think we can resolve all code related issues one way or another, but since I'm not making decisions here anymore, we should make sure the team actually wants this feature before we put anymore time into it.

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.

3 participants