Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

ddiddles posted:

Is there a best practice when using API calls in a React/Redux based site?

I'm trying to get my head around the structure of an idea I have for a personal project to try and learn a more modern way to build a site.

It's going to be a site that lets you view upcoming private space launches, I also wanted a user to be able to click on a company name and get more information about them. All data will be stored in Firebase.

I'm not to clear on what the logic flow should be, I'm thinking something like this:

1. User visits http://website.com/company/companyName
2. The company component dispatches a "start fetching company data" Redux action, using the companyName as a parameter to search the DB with.
3. The Redux action uses Thunk as middleware to fetch the object holding that companies info from the Firebase DB, then passes that into a "finished grabbing company data" action, which causes the reducer handling that action to update the store, which causes the company component to re render with the new data.

Is having the API call logic inside an async redux action a common practice (was planning on having all the API logic in it's own module that exports the specific fetch/update/delete functions, which I import into the redux actions module)?

Or is my thinking totally off?

That's it.

An async action is fired, when the request / firebase update is done, you fire another action.

For Firebase, you can do fancy stuff to listen to changes on the DB instance and have actions trigger automatically if you are in to that.

Adbot
ADBOT LOVES YOU

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION

Lumpy posted:

https://egghead.io/courses/getting-started-with-redux
https://egghead.io/courses/building-react-applications-with-idiomatic-redux

Better to spend 3 hours learning than spend 100 hours writing code that doesn't work well.

Just want to say I've been watching these videos and they've already helped me understand things a LOT better, thanks!

putin is a cunt
Apr 5, 2007

BOY DO I SURE ENJOY TRASH. THERE'S NOTHING MORE I LOVE THAN TO SIT DOWN IN FRONT OF THE BIG SCREEN AND EAT A BIIIIG STEAMY BOWL OF SHIT. WARNER BROS CAN COME OVER TO MY HOUSE AND ASSFUCK MY MOM WHILE I WATCH AND I WOULD CERTIFY IT FRESH, NO QUESTION

Lumpy posted:

That's it.

An async action is fired, when the request / firebase update is done, you fire another action.

For Firebase, you can do fancy stuff to listen to changes on the DB instance and have actions trigger automatically if you are in to that.

One thing I'm unclear on, where exactly is the "fetch company data" action dispatched FROM? I mean, generally you might use an onClick or something to trigger the dispatching of an action, what do you use if you want to immediately dispatch the action when the component loads? Is it acceptable to use the lifecycle methods for this?

Ochowie
Nov 9, 2007

The Wizard of Poz posted:

Is it acceptable to use the lifecycle methods for this?

I hope so. Otherwise I've been doing it wrong.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

The Wizard of Poz posted:

One thing I'm unclear on, where exactly is the "fetch company data" action dispatched FROM? I mean, generally you might use an onClick or something to trigger the dispatching of an action, what do you use if you want to immediately dispatch the action when the component loads? Is it acceptable to use the lifecycle methods for this?

Generally to have a component auto-load data you'd use componentWillMount and fire an action there if the state doesn't have what it needs.

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
I don't understand why there is not much documentation on creating constructors in React. Are you even able to create constructors in React? Is this what they mean when they say React is only the "V" in MVC?

Should I just do this stuff if Javascript and then render the results in React?

Basically what I'm asking is how does something like this translate to React code?

code:
function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
var myFather = new person("John", "Doe", 50, "blue");
var myMother = new person("Sally", "Rally", 48, "green");
My ultimate goal is to get values from a form, use those values as the arguments in the new instance of a constructor, and then push that new object to an array. I'm just not sure if React is capable of that.

teen phone cutie fucked around with this message at 05:39 on Jan 26, 2017

Kekekela
Oct 28, 2004
e: never mind, that looks way more comprehensive VVV

Kekekela fucked around with this message at 06:16 on Jan 26, 2017

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



Grump posted:

I don't understand why there is not much documentation on creating constructors in React. Are you even able to create constructors in React? Is this what they mean when they say React is only the "V" in MVC?

Should I just do this stuff if Javascript and then render the results in React?

Basically what I'm asking is how does something like this translate to React code?

code:
function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
var myFather = new person("John", "Doe", 50, "blue");
var myMother = new person("Sally", "Rally", 48, "green");
My ultimate goal is to get values from a form, use those values as the arguments in the new instance of a constructor, and then push that new object to an array. I'm just not sure if React is capable of that.

React is a library handling only the view part of an application. The only thing it's concerned about is creating components that will be rendered, and rendering the component to a target (99% of times that's the DOM on a web page, the other 1% is something like React-native where React is handling only the view part of a non-web application).

How you create and modify data is entirely up to you. The only thing React asks you to do is to call Component.setState() when a state changes.

code:
function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
var myFather = new person("John", "Doe", 50, "blue");
var myMother = new person("Sally", "Rally", 48, "green");


var PersonComponent = React.createClass({
    render: function() {
        var person = this.props.person;

        return <div>
            <h1>My name is {person.firstName} {person.lastName}</h1>
            <p>The other poo poo: {person.age}, {person.eyeColor}</p>
        </div>;
    }
});

PersonComponent.propTypes = {
  person: React.PropTypes.object
};


ReactDOM.render(<PersonComponent person=myFather/>, document.getElementById('root'));
But that has the person as a prop instead of state. If person ever changes then it needs to be sent down to the component as a prop again from something higher up. Let's do it again but with the person as an internal piece of state to the component:

code:
function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}

var age = 50;

var PersonComponent = React.createClass({
    getInitialState: function() {
        return {
            person: new person("John", "Doe", age, "blue")
        }
    },

    componentDidMount: function() {
        //TODO: clear interval in componentWillUnmount or all 
        //hell breaks loose when this component gets unmounted
        setInterval(() => this.tick(), 1000);
    },

    tick: function() {
        age++;

        this.setState({
            person: new person("John", "Doe", age, "blue")
        })
    }

    render: function() {
        var person = this.state.person;

        return <div>
            <h1>My name is {person.firstName} {person.lastName}</h1>
            <p>The other poo poo: {person.age}, {person.eyeColor}</p>
        </div>;
    }
});



ReactDOM.render(<PersonComponent/>, document.getElementById('root'));
When the component is added to the DOM (componentDidMount), it sets up an interval every 1000ms to create a new person and calls setState with the new person. setState updates the component's state and triggers a re-render, and the new person's age will be reflected on screen.

I'm going to redo this with ECMAScript 6 too since it'll be nicer looking:

code:
class Person {
    constructor(first, last, age, eye) {
        this.firstName = first;
        this.lastName = last;
        this.age = age;
        this.eyeColor = eye;
    }
}

let age = 50;

class PersonComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            person: new person("John", "Doe", age, "blue")
        }
    }

    componentDidMount() {
        //TODO: clear interval in componentWillUnmount or all 
        //hell breaks loose when this component gets unmounted
        setInterval(() => this.tick(), 1000);
    }

    tick() {
        age++;

        this.setState({
            person: new Person("John", "Doe", age, "blue")
        })
    }

    render() {
        var person = this.state.person;

        return <div>
            <h1>My name is {person.firstName} {person.lastName}</h1>
            <p>The other poo poo: {person.age}, {person.eyeColor}</p>
        </div>;
    }
};



ReactDOM.render(<PersonComponent/>, document.getElementById('root'));
And since Dan Abramov keeps going on about setState also being able to take a reduce function, you can and probably should do something like this:

code:
class Person {
    constructor(first, last, age, eye) {
        this.firstName = first;
        this.lastName = last;
        this.age = age;
        this.eyeColor = eye;
    }
}

class PersonComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            person: new person("John", "Doe", 50, "blue")
        }
    }

    componentDidMount() {
        //TODO: clear interval in componentWillUnmount or all 
        //hell breaks loose when this component gets unmounted
        setInterval(() => this.setState(this.tick), 1000);
    }

    tick(oldState) {
        let oldPerson = oldState.person;

        let {
            firstName,
            lastName,
            age,
            eyeColor
        } = oldPerson;

        return {
            person: new Person(firstName, lastName, age + 1, eyeColor)
        };
    }

    render() {
        var person = this.state.person;

        return <div>
            <h1>My name is {person.firstName} {person.lastName}</h1>
            <p>The other poo poo: {person.age}, {person.eyeColor}</p>
        </div>;
    }
};



ReactDOM.render(<PersonComponent/>, document.getElementById('root'));
But first read the React tutorials on their homepage and read about the Flux architecture pattern and about some Redux for how to structure this better.

edit: Also since I can be more specific to what you want to do, for your form component all you need to do is have a method on your component for when you want to create the person object (I'm going to assume it's something like "user pressing the enter key"). In that method just create the new person instance as if this was regular plain vanilla JS (because it is!), and push that instance to your array that is holding people (I'm guessing you want to pass the array in to the component as a prop).

If you have another component that is rendering the contents of that array then you'll need to signal to that component that the array's contents have changed. Have the form component take in something that you can dispatch events on as a prop, and dispatch it with the new instance, then have the rendering component subscribe to that event and have the component call setState with the new array. setState triggers a call to render, render takes in the new state property with the array with your new person instance, and renders like normal.

piratepilates fucked around with this message at 06:31 on Jan 26, 2017

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Possibly that example would be better if age was this._age or something, otherwise when it ticks all usages of the component.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Grump posted:

I don't understand why there is not much documentation on creating constructors in React. Are you even able to create constructors in React? Is this what they mean when they say React is only the "V" in MVC?

Should I just do this stuff if Javascript and then render the results in React?

Basically what I'm asking is how does something like this translate to React code?

code:
function person(first, last, age, eye) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eye;
}
var myFather = new person("John", "Doe", 50, "blue");
var myMother = new person("Sally", "Rally", 48, "green");
My ultimate goal is to get values from a form, use those values as the arguments in the new instance of a constructor, and then push that new object to an array. I'm just not sure if React is capable of that.

To reiterate what piratepilates said in other terms: React *shouldn't* have that stuff in there. React renders what you tell it to, that's it. Obviously a simplification, but yeah, React is the V. Your model can be whatever you want (Redux, Angular, plain old JS you write yourself, an external API / Firebase) and you use actions to let the view inform the model (or controller, or whatever) that something happened in your app. Your code is then responsible for passing new state to your view when something changes outside of it (an API request completed or failed, etc.)

In my React apps, React is about 10-20% of the code. You can build a functional, unit tested Redux app that's "feature complete" before you even npm -i react.

Pollyanna
Mar 5, 2005

Milk's on them.


So I'm having trouble justifying the use of standard HTML5 elements like number inputs since they only partially accomplish what the designers and POs want. The min and max properties on number fields don't prevent users from manually typing in numbers outside of those limits, so the designers+POs reject that approach. I was under the impression that we should favor HTML5 elements when possible, but we keep running into stupid issues with Firefox, Safari, and Edge as a result. Am I missing something here?

Also I don't think the PMs and POs understand that I can't make entire tech stack/frontend framework decisions on my own. Hell, I'm not even a frontend engineer. :psyduck:

Pollyanna fucked around with this message at 19:15 on Jan 26, 2017

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Pollyanna posted:

So I'm having trouble justifying the use of standard HTML5 elements like number I puts since they only partially accomplish what the designers and POs want. The min and max properties on number fields don't prevent users from manually typing in numbers outside of those limits, so the designers+POs reject that approach. I was under the impression that we should favor HTML5 elements when possible, but we keep running into stupid issues with Firefox, Safari, and Edge as a result. Am I missing something here?

Also I don't think the PMs and POs understand that I can't make entire tech stack/frontend framework decisions on my own. Hell, I'm not even a frontend engineer. :psyduck:

You should be able to hook into the default input field and either attach an onchange or onkeypress and do validation there. If you only want users to type in 1-5, just straight up deny those inputs.

Pollyanna
Mar 5, 2005

Milk's on them.


That handles the manual input issue, yes, which is a shame since I expected min and max to be more powerful than that. It still doesn't help the HTML5 stuff and the fact that I thoroughly dislike frontend, but at least it can do something. :sigh:

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Skandranon posted:

You should be able to hook into the default input field and either attach an onchange or onkeypress and do validation there. If you only want users to type in 1-5, just straight up deny those inputs.

Or be ghetto and use the pattern attribute and then get complaints that it doesn't work on blah blah blah....

Front End. Front End never changes.....

teen phone cutie
Jun 18, 2012

last year i rewrote something awful from scratch because i hate myself
Thanks piratepilates and Lumpy. Really helpful stuff!

HaB
Jan 5, 2001

What are the odds?

Pollyanna posted:

That handles the manual input issue, yes, which is a shame since I expected min and max to be more powerful than that. It still doesn't help the HTML5 stuff and the fact that I thoroughly dislike frontend, but at least it can do something. :sigh:

I realize min/max doesn't prevent a user from entering a value outside of a range, but I'm pretty sure it will set some sort of flag on form submit, which can be hooked by whatever is performing your validation.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



HaB posted:

I realize min/max doesn't prevent a user from entering a value outside of a range, but I'm pretty sure it will set some sort of flag on form submit, which can be hooked by whatever is performing your validation.

And you can use the :invalid pseudoclass to make it an angry color and add an :after or whatever.

E: to clarify, :invalid is set automatically if the input has invalid content (and is set to required, IIRC)

Munkeymon fucked around with this message at 20:54 on Jan 26, 2017

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Munkeymon posted:

And you can use the :invalid pseudoclass to make it an angry color and add an :after or whatever.

E: to clarify, :invalid is set automatically if the input has invalid content (and is set to required, IIRC)

I think the problem is the people complaining don't want just validation saying "You can't type that plz fix", but a hard lockdown on a bad value ever even appearing in the input box. Likely, because reasons.

Pollyanna
Mar 5, 2005

Milk's on them.


Skandranon posted:

I think the problem is the people complaining don't want just validation saying "You can't type that plz fix", but a hard lockdown on a bad value ever even appearing in the input box. Likely, because reasons.

That's exactly it. I feel that barring the user too much from entering certain inputs might just piss them off more than anything, really.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



^^you are the correct one here, yes^^

Skandranon posted:

I think the problem is the people complaining don't want just validation saying "You can't type that plz fix", but a hard lockdown on a bad value ever even appearing in the input box. Likely, because reasons.

Yeah, they wrote up a requirement for a UI that's actually kind of annoying and counterintuitive to use (and hard to make accessible!), but neat in their heads. Then it probably got estimated to take as much time to implement as typing out the markup, just to ice that cake.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
On the topic of setting up grown-up projects, I wanted to bring up looking for projects on GitHub that are simply templates combining some of the major technologies. This doesn't entirely help you lay out lots of files, but it gives you a config people use for normally building and deploying their project. I was seeing a lot of that while I was figuring out how to get Webpack working with Karma and Jasmine. It would have been great to have found all that when I was first starting out, but it would have been impossible; they rely on knowing all the magic words already.

Skandranon posted:

So, when unit testing Angular apps, keep in mind your Angular code has to actually be there, as well as the libraries you are using, like Angular. So you have to load Angular, the code that defines your module, etc, before you start any tests.

In your case, it is probably choking on module, as it should be angular.mock.module("moduleName"); This will instantiate your module. You can then start instantiating Services, Controllers, Components, etc, from that module, and executing code against it.

To make testing easier, it's a good idea to not put all your code in the same module, as you have to deal with bootstrapping the whole thing at once. It is much easier to have small modules, so you can test them individually.

It's been a bit but I wanted to update that I did end up getting it working at the end of last week. I had to do some stuff to get it to recognize angular.mock and then was able to specify the module. It was just a little massaging after that.

I guess all these unit test/Webpack examples online really are to put each test suite into its own bundle. I don't get why I'd want to do that. So all the stuff I was installing was setting me up for that, even though all I wanted to do was use my regular old bundle.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

Rocko Bonaparte posted:

On the topic of setting up grown-up projects, I wanted to bring up looking for projects on GitHub that are simply templates combining some of the major technologies. This doesn't entirely help you lay out lots of files, but it gives you a config people use for normally building and deploying their project. I was seeing a lot of that while I was figuring out how to get Webpack working with Karma and Jasmine. It would have been great to have found all that when I was first starting out, but it would have been impossible; they rely on knowing all the magic words already.


It's been a bit but I wanted to update that I did end up getting it working at the end of last week. I had to do some stuff to get it to recognize angular.mock and then was able to specify the module. It was just a little massaging after that.

I guess all these unit test/Webpack examples online really are to put each test suite into its own bundle. I don't get why I'd want to do that. So all the stuff I was installing was setting me up for that, even though all I wanted to do was use my regular old bundle.

You don't need to use Webpack for your testing at all. You can build your application bundle via Webpack, then pass the completed bundle to be tested by your unit test framework, which is entirely separate.

HaB
Jan 5, 2001

What are the odds?

Pollyanna posted:

That's exactly it. I feel that barring the user too much from entering certain inputs might just piss them off more than anything, really.

Yeah after nearly 20 years in this business - I don't think I have EVER seen that strategy work. It makes the app feel aggressive/restrictive to the user. Let them type whatever and then validate when they try to save it. They will learn quickly as long as the validation error messages are clear. "Derp Range must be between 5 and 22 derps"

I realize it's not your call and my last statements aren't directed directly at you - I mean the global "you". ;)

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



HaB posted:

Yeah after nearly 20 years in this business - I don't think I have EVER seen that strategy work. It makes the app feel aggressive/restrictive to the user. Let them type whatever and then validate when they try to save it. They will learn quickly as long as the validation error messages are clear. "Derp Range must be between 5 and 22 derps"

I realize it's not your call and my last statements aren't directed directly at you - I mean the global "you". ;)

Has anyone published papers about these things? Seems very easy to test and would be very useful insight.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

piratepilates posted:

Has anyone published papers about these things? Seems very easy to test and would be very useful insight.

Yes, but the marketing department knows that they don't apply to *their* app.

smackfu
Jun 7, 2004

I like input fields with a minimum length check that run the check after the first keystroke. So you can't even enter a valid value without first triggering the errors.

Skandranon
Sep 6, 2008
fucking stupid, dont listen to me

smackfu posted:

I like input fields with a minimum length check that run the check after the first keystroke. So you can't even enter a valid value without first triggering the errors.

I like password fields that have min/max length that a) don't actually correspond to backend restrictions and b) are not consistent across the application.

Pollyanna
Mar 5, 2005

Milk's on them.


Lumpy posted:

Yes, but the marketing department knows that they don't apply to *their* app.

Or our first-pass designers are just morons, in our case.

Pollyanna
Mar 5, 2005

Milk's on them.


smackfu posted:

I like input fields with a minimum length check that run the check after the first keystroke. So you can't even enter a valid value without first triggering the errors.

This is why it is important to know the difference between onChange and onBlur :eng101:

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Pollyanna posted:

This is why it is important to know the difference between onChange and onBlur :eng101:

Or to know how to write non-stupid onChange handlers :science:

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Yeah, if you wanna validate during typing, debounce it and set some minimums so the user is actually done typing before you validate, especially if involves a server process.

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice
With the discussions the last week about Redux/React project structure, this article I just came across seems appropriate: https://medium.freecodecamp.com/scaling-your-redux-app-with-ducks-6115955638be#.geaggdjdi

Pollyanna
Mar 5, 2005

Milk's on them.


I'm tempted to just roll my eyes and say "whatever" at the people who want natural language forms exactly like https://www.ladderlife.com/get-quote and https://havenlife.com/term-life-insurance-quote.html and are unquestioningly pushing for us copying them down to the letter. I'm not a UX/UI designer, but I still feel like being THAT restrictive on things like date input might just annoy users. But, I'm also getting pushback on a PM over this (I don't know who else is in charge of design, user acceptance, etc. for this subject) who is really in the tank for it, so v:goleft:v It'd be less effort and headache for me to just go with it, even if users end up disliking it.

Edit: hahaha one of those date inputs doesn't even work right on mobile.

Lumpy posted:

With the discussions the last week about Redux/React project structure, this article I just came across seems appropriate: https://medium.freecodecamp.com/scaling-your-redux-app-with-ducks-6115955638be#.geaggdjdi

Nice. I prefer the feature over function approach myself, it's much better organized.

Pollyanna fucked around with this message at 18:05 on Jan 30, 2017

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Using an actual type="date" to enter a birthday is currently a bad idea because the Android date control only lets you jog one month at a time, defaults to the current date and is really easy to set to the current date (accidentally press any of the green part at the top of the overlay in the image below!), so any adult is going to have to tap a stupid button 200+ times to get anywhere near their birthday.

Munkeymon fucked around with this message at 19:02 on Jan 30, 2017

Pollyanna
Mar 5, 2005

Milk's on them.


Munkeymon posted:

Using an actual type="date" to enter a birthday is currently a bad idea because the Android date control only lets you jog one month at a time, defaults to the current date and is really easy to set to the current date (accidentally press any of the green part at the top of the overlay in the image below!), so any adult is going to have to tap a stupid button 200+ times to get anywhere near their birthday.



gently caress it then, people are used to writing their birthdays down, so as long as the text approach is done in a smart fashion, it's fine.

The Merkinman
Apr 22, 2007

I sell only quality merkins. What is a merkin you ask? Why, it's a wig for your genitals!

Munkeymon posted:

Using an actual type="date" to enter a birthday is currently a bad idea because the Android date control only lets you jog one month at a time, defaults to the current date and is really easy to set to the current date (accidentally press any of the green part at the top of the overlay in the image below!), so any adult is going to have to tap a stupid button 200+ times to get anywhere near their birthday.



You can tap the year to change it :science:

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



The Merkinman posted:

You can tap the year to change it :science:

JFC what a poo poo stupid design but hey that's Google and therefore Android for you.

Horn
Jun 18, 2004

Penetration is the key to success
College Slice
e: wrong thred

Lumpy
Apr 26, 2002

La! La! La! Laaaa!



College Slice

Munkeymon posted:

JFC what a poo poo stupid design but hey that's Google and therefore Android for you.

I also like the fact that cancel and OK are the same color. Totally minor compared to completely concealing some rather important functionality, but...

Adbot
ADBOT LOVES YOU

Mr Shiny Pants
Nov 12, 2012
iOs is the same, went from a really discoverable UI to that flat stuff on which you just press things to see if they may interact.

Don't get me started on 3d push that works on some models and not on others.

That's what you get when stuff is "finished" but you just can't leave it alone.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply