Assistance Appreciated - One Button, Two LEDs with Timing While Pressed

Thanks in advance for any help.

Scenario Overview

In the real world, I am using one button to open two mechanical valves, but one of those valves should close after a period of time that we will hard code into the sketch, and the other valve stays open for as long as the button is pushed. For proof of concept, I am lighting two LEDs as stand-ins for the valves.

Pseudocode

If Button One is pressed, Valve One should Open, and Valve Two should also Open for 200ms then Close.

Initial Solution

Within the main loop, I look for the button to be pushed as part of an if statement. When that condition is passed, I used a while loop and timer to keep "valve2" open until the time is up. LEDs work, and all is superficially great. However...

The Issue

When my partner starts putting the actual mechanicals together, valve2 doesn't open because the while loop is cycling so quickly that the voltage required to initiate the opening of the valve is not high enough.

My Question

Is it possible to isolate (without using delays) the loop & evaluation of the timer condition from the main loop in order to allow full power to be sent to the valve mechanism (or LED in this case)? Or am I overthinking this whole thing (likely the case)?

The Code

        const int button1 = 2;      //Pin for switch 1
        const int button2 = 3;      //Pin for switch 2
        const int valve1 = 12;    //Pin for relay 1
        const int valve2 = 13;    //Pin for relay 2

        // variables will change:
        int state1 = 0;         // variable for reading the pushbutton status
        int state2 = 0;         // variable for reading the pushbutton status

        //THIS IS THE TIME IN MILLISECONDS FOR valve2 WHEN button1 IS DEPRESSED
        int valve2time = 200;

        void setup() {
          //switches
          pinMode(button1,INPUT);       //Set button1 as input
          pinMode(button2, INPUT);     //Set button2 as input
          //relays
          pinMode(valve1, OUTPUT);      //Set valve1 as output
          pinMode(valve2, OUTPUT);      //Set valve2 as output
          Serial.begin(9600);
        }

        void loop(){
          state1 = digitalRead(button1);              //state1 returns the state of button1, up or down.
          state2 = digitalRead(button2);              //state2 returns the state of button2, up or down.
          int duration = switchTime();            //Create variable to capture duration of switch press

          if (state1 == LOW && state2 == LOW){     //if no buttons are pressed
            digitalWrite(valve1,LOW);                //make sure valve1 is off
            digitalWrite(valve2,LOW);                //make sure valve2 is off

          }
          else if (state1 == HIGH && state2 == LOW) { //if JUST button one is pressed    
            digitalWrite(valve1,HIGH);               //turn on valve1

            while (duration <= valve2time){           //as long as the timer is below or = to what we defined up top....
              digitalWrite(valve2,HIGH);             //...Turn on valve2...
              break;                               //...Then stop the while loop...
            }

            digitalWrite(valve2,LOW);                //...and finally turn off valve2

          }
          else if (state2 == HIGH){              //final condition, if button two is pressed
            digitalWrite(valve1,HIGH);               //turn on valve1
            digitalWrite(valve2,HIGH);               //turn on valve2
          }

        }


        //return the time in ms that the switch has been pressed (LOW) 
        long switchTime(){
          //these variables are static
          static unsigned long startTime = 0;   //the time the switch state was first detected
          static boolean state;         //the current state of the switch

          if(digitalRead(button1) != state){    //check to see if the switch has changed state
            state = ! state;                //yes, invert the state
            startTime = millis();           //store the time
          }

          if(state == HIGH){
            return millis() - startTime;    //switch pushed, return time in ms
          }
          else{
            return 0;                   //return 0 if the switch is not pushed (in the HIGH state)
          }

        }

What is to happen if the button is released before the hard coded time has ended?
Should LED1 stay on until the time is up and LED2 go off immediately or should they both go off immediately?

Pseudo code:

byte flag = 0
if button pressed and flag = 0 {
set start time
turn on led 1 
turn on led 2
flag = 1}
else if button pressed
if time elapsed{
turn off led 1}
if button released{
turn off led 2
flag = 0
turn off led 1? (see my previous post)
}

For timing using millis(), see the 'blink without delay' example in the examples page of this site or in the IDE.

The demo several things at a time illustrates how to use millis() to manage timing without blocking.

...R

Henry_Best:
What is to happen if the button is released before the hard coded time has ended?
Should LED1 stay on until the time is up and LED2 go off immediately or should they both go off immediately?

Thanks for replying. Both LED1 and LED2 go off immediately. I'll look at your other replies now.

Robin2:
The demo several things at a time illustrates how to use millis() to manage timing without blocking.

...R

Great demo. A lot of good lessons in there. It'll take me a little while to fully understand, but I think it's a great place to start and reference. I especially like the debounce feature on the button.