Sternbach-Software / GeniForAndroid

Geni.com Android app
GNU General Public License v3.0
3 stars 1 forks source link

Replace "magic numbers" with IntDef #9

Open Sternbach-Software opened 1 year ago

Sternbach-Software commented 1 year ago

A magic number is "a unique value with unexplained meaning or multiple occurrences which could (preferably) be replaced with a named constant" - Wikipedia.

There are many instances where a number is used as a case in a switch or if statement to specify which action should be done (e.g. if(action == 5) { //create note), and it is a practice that has been found to often introduce bugs and reduce code readability.

The preferred solution in Android is to replace it with an IntDef.

Here are some examples that need changing (some are links to function definitions, so all calls to that function need to change; likewise for variables):

whittede commented 1 year ago

Great explanation and intro to the work! @Sternbach-Software do you mind assigning me to this task?

Thanks!

whittede commented 11 months ago

@Sternbach-Software I finally have some time to begin dipping my toes into this project. I've initiated a pull request here to see if development is still able to happen on this project, or if you/anyone else are no longer planning on moving it forward.

Sternbach-Software commented 11 months ago

@whittede development has kind of stagnated for 3 reasons:

whittede commented 11 months ago

Oh, wow! Well that's some very impressive dedication and work, I like the plan! I was also very impressed with your transition of the entire codebase from Java to Kotlin originally, to be honest.

Let me know if there is anything I can do in terms of Googling or skills I could learn to help draw visual lines between the family trees in the app if that's something you'd like help with! I still think this project is a great idea that a ton of people will benefit from.

Good to hear from you, just let me know if/when you have a slot that can require some additional help!

El sáb., 12 de agosto de 2023 22:52, Sternbach-Software < @.***> escribió:

@whittede https://github.com/whittede development has kind of stagnated for 3 reasons:

  • I started developing the SDK for the API https://github.com/Sternbach-Software/GeniAndroidSDK, but I couldn't figure out how to return specific values from the API.
  • I am thinking of moving the app to Kotlin Multiplatform so that it will be an iOS, Android, web, and desktop app with a single codebase. In the process, I would want to reimplement all of the guts in a cleaner way.
  • the only thing stopping me from doing the above is that I need a Compose family tree view. I have started developing one, but I need to figure out how to draw the lines between family members. Once I do that, it will be ready for use, and I will likely build the app from scratch.

— Reply to this email directly, view it on GitHub https://github.com/Sternbach-Software/GeniForAndroid/issues/9#issuecomment-1676240231, or unsubscribe https://github.com/notifications/unsubscribe-auth/AIM3JMHVFBKZZPKOITDADN3XVBTTTANCNFSM6AAAAAASHD2NSQ . You are receiving this because you were mentioned.Message ID: @.***>

Sternbach-Software commented 11 months ago

The API SDK is not too hard. If you can get a working API request with specific field returned, that would be great. You can use something like postman, or write a script in python, Java, or Kotlin (preferably the latter).

I think the lines thing is pretty complicated. You can take a stab at it by googling Compose Layout (the Layout composable).

Conceptually, the algorithm I am working on to draw a line connecting all children is as follows: Theory: a line comes out from each child’s center-top and connects to a horizontal line which extends from the left-most child to the right-most child. screenshot_2023-07-06_at_1.18.26_am.png

  1. Draw a straight line up from each child’s center-top (x = child center, y = child top) until parent’s bottom y ( (x = child center, y = parent bottom)
  2. Let startX = left-most child’s center-top
  3. Let endX = right-most child’s center-top
  4. Draw a line from startX to endX

Then, to connect the children to the parents, and the parents to each other:

  1. Draw a line from parent's middle (x = if(left parent) end x else start x, y = parent.height / 2) to halfway between parents (x = (end of left parent x + start of right parent x) / 2, = parent.height / 2). This connects parents.
  2. Draw a line from halfway between parents to horizontal line connecting children (x = (end of left parent x + start of right parent x) / 2), y = parent bottom) There should probably be some padding between the horizontal child line and the parent bottom, but that is (hopefully) trivial.

The question is how to do this in Compose. This code lays out the children fine:

/**
 * Every person/[FamilyTree] is responsible for drawing themselves and their children.
 * */
@Composable
fun FamilyTree(
    modifier: Modifier = Modifier,
    root: Person,
) {
    val backgroundColor = colors.random(random) //for debug: draw bounding box to see bounds of this person
​
    Column(
        modifier
            .fillMaxWidth()
            .drawWithContent { //draw debug background
                drawRect(backgroundColor)
                drawContent()
            },
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Row(
            horizontalArrangement = Arrangement.Center
        ) {
            root.spouse?.let { PersonCard(it, Color.Magenta) }
            PersonCard(root, color = backgroundColor)
        }
​
        //Draw their children
        if (root.children.isNotEmpty()) {
            Row(horizontalArrangement = Arrangement.Center) {
                for (child in root.children) {
                    FamilyTree(
                        root = child.copy(name = "${child.name} sonOf ${root.name}"), //name change for debug purposes
                    )
                }
            }
        }
    }
}
​
@Composable
fun PersonCard(person: Person, color: Color) {
    Card(
        modifier = Modifier
            .padding(8.dp)
            .width(100.dp),
        colors = CardDefaults.cardColors(color)
    ) {
        Text(person.name)
    }
}
whittede commented 11 months ago

I'm on it! I'll take a crack at this in September and I'll ask some questions here as they come up. (I'm sure they will.)

Where is Geni's API endpoint that we are attempting to connect to with the SDK? That's where I will start plugging away at first to see if I can get some specific fields returned. Thanks!

Sternbach-Software commented 11 months ago

https://www.geni.com/platform/developer/help/reference?version=1

whittede commented 10 months ago

Hey @Sternbach-Software ! Just to post an update here in September, as promised:

I believe I'm 99% of the way there getting the Geni API to return specific values, but the last remaining issue I am running into is that on the final step, in which the API should be giving me an access token (according to here), I am instead getting the error {"error_description":"Invalid authorization code","error":"invalid_request"} returned. My scripts for executing the AJAX API calls are all in Javascript.

I've run out of time to work on this, so I will have to chase down this issue and fix it in October or November. I'll let you know when I resolve it. Should we move any future discussion about connecting to the API to a different thread?

Hope you're doing well! Thanks!

Sternbach-Software commented 10 months ago

Do you have an Android phone? I made an app that gets the access token using my registered Geni app id and callback URL, but the URL looks something like geniforandroid://access_token?ACCESS_TOKEN=ABC123. This works on Android because apps can intercept specific URLs and have them redirect to specific code which can read the URL, so when the browser that the user used to approve access tries to navigate to the above URL, our app is opened and the code I wrote saves the access token to a database. I am not sure how to reproduce that interception from the command line.

whittede commented 6 months ago

Hey @Sternbach-Software!

I set aside some time for myself to work on this in December as promised, but when the time came around, Christmas season was really packed and my wife asked if I could push my hobby project to January. Then I purchased a new laptop, so I reinstalled all of my web server setup onto this laptop when I started developing this month!

I am very close to getting the API to return a value that I want, but currently I am receiving a different error for each API endpoint that I try to access, so I need to choose a specific endpoint and just focus on that.

I've posted a question to the Geni Developers Forum regarding the /api/user/metadata endpoint, so hopefully I can get some assistance with the rate limits. If I don't receive a response there, I'll re-post the question onto Stack Overflow, and if that doesn't work then I was just recently on a video call with Geni's General Manager, so I will send him a send him a message and see if he can give me some help.

Anyway, I will keep plugging away at the API and I'll keep you updated on the responses I get!

Sternbach-Software commented 6 months ago

@whittede thanks so much! I have also been plugging away on the family tree component. Tried many different variations and resources so far, including looking at other languages. Turns out it is a very complicated problem.

whittede commented 6 months ago

Haha we'll eventually get somewhere! The code can't stump us for long!

Sternbach-Software commented 5 months ago

@whittede I finally got it (mostly)! I was able to create a composable that can start from an ancestor and draw their spouse, chlidren, and each child's spouse.

However, like with many other family tree components, it can't yet start climbing back up a tree in middle of climbing down the tree (e.g. drawing my children, drawing my children-in-laws, and then drawing my children-in-laws' parents).

This also only works for descendants, not ancestors (the more common use case). I am looking into how easily I can reverse the tree, so it can be used to display ancestors.

Sternbach-Software commented 5 months ago

Screenshot 2024-02-04 at 5 15 18 AM

Sternbach-Software commented 5 months ago

Notice how the first family also has an issue rendering. I am not yet sure why.

whittede commented 5 months ago

Hey, fantastic work @Sternbach-Software !! That's great news, thanks for sharing! It's looking really good! I can't wait to see it be able to begin climbing back up the tree and draw nodes who are not direct descendents, but this is a big step forward.

Regarding the API I've done a bit more picking away at it and have learned some new information about how HTTP headers are exposed but I am still unable to figure out how to see the rate limit information that Geni is supposedly passing me, and thus can't diagnose why I am getting rate limited in the first place. Since I have not received a response (except from you, today 😉) on the Geni Developer Forum, I've refined the question even more and posted it to StackOverflow, as promised: https://stackoverflow.com/questions/77937275/where-are-the-exposed-headers-informing-my-rate-limit-for-the-geni-api

If I still can't get any response even there in the next week, I will reach out to Geni's General Manager since I've chatted with him before and see if he can help me diagnose the issue and determine if it is an issue on Geni's side.

I'll be back with an update in about a week or so if I don't hear anything sooner! Excited about where this is going!

whittede commented 5 months ago

Okay, great update from me today! I dumped a whole bunch more hours into troubleshooting this issue with the HTTP headers and finally got things resolved! I'm still receiving an error that I'm tripping the rate limit for Geni's API on some of my calls, but I can see the info I need to resolve that now, and I am able to make my code a lot more robust to help in situations like that for this and future projects I work on.

My next step is going to be to update a piece of my proxy server code that is necessary to make API requests like this so that it is much more robust and can handle situations like the one I am encountering with the Geni API. @Sternbach-Software my next set-aside time that I should be able to tackle this will be at the beginning of April, after Easter. (Things are pretty full until then.) I'll give you an update when I next tackle some of this!

whittede commented 3 months ago

I was going to work on the API issues some more today, as scheduled, but I'm realizing that's going to take quite a few hours that I don't have today, so I'm actually going to move my work on this to later this month, when my wife is out on a trip. I'll give an update then after I've put some more work into it!

whittede commented 3 months ago

I had plenty of time this weekend as planned, but ended up spending the weekend coding a different personal project instead haha I'm trying to get a script running on a Rasberry Pi board to make my life a little bit easier. So oops, I'll get back to the Geni API for the app in mid-May instead. 😛