moved all state out of listener