App-MatrixClient

 view release on metacpan or  search on metacpan

lib/App/MatrixClient/RoomTab.pm  view on Meta::CPAN

         if( $changes{topic} ) {
            $self->append_line( format_topic_change( $member, $changes{topic}[1] ),
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            );
            $self->update_headline;
         }
         foreach ( map { m/^level\.(.*)/ ? ( $1 ) : () } keys %changes ) {
            $self->append_line( format_roomlevel_change( $member, $_, $changes{"level.$_"}[1] ),
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            );
         }
      },
      on_back_state_changed => sub {
         my ( undef, $member, $event, %changes ) = @_;

         if( $changes{name} ) {
            $self->prepend_line( format_name_change( $member, $changes{name}[0] ),
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            );
         }
         if( $changes{aliases} ) {
            $self->prepend_line( $_,
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            ) for format_alias_changes( $event->{user_id}, @{ $changes{aliases} }[1,0] );
         }
         if( $changes{topic} ) {
            $self->prepend_line( format_topic_change( $member, $changes{topic}[0] ),
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            );
         }
         foreach ( map { m/^level\.(.*)/ ? ( $1 ) : () } keys %changes ) {
            $self->prepend_line( format_roomlevel_change( $member, $_, $changes{"level.$_"}[0] ),
               time => ( $event->{origin_server_ts} // $event->{ts} ) / 1000,
            );
         }
      },

      on_presence => sub {
         my ( undef, $member, %changes ) = @_;
         $self->update_member_presence( $member );
      },

      on_members_typing => sub {
         my ( undef, @members ) = @_;

         @members or
            $self->set_typing_line( undef ), return;

         my $s = String::Tagged->new
            ->append_tagged( " # currently typing: ", fg => "magenta" );

         my $last_member = pop @members;
         $s->append_tagged( format_displayname( $_ ) )
           ->append( ", " ) for @members;
         $s->append_tagged( format_displayname( $last_member ) );

         $self->set_typing_line( $s );
      },
   );

   $room->add_child( $self->{typing_grace_timer} = IO::Async::Timer::Countdown->new(
      delay => TYPING_GRACE_SECONDS,
      on_expire => sub { $room->typing_stop },
   ) );
}

sub append_line
{
   my $self = shift;

   if( $self->{typing_line} ) {
      my @after = $self->{scroller}->pop;
      $self->SUPER::append_line( @_ );
      $self->{scroller}->push( @after );
   }
   else {
      $self->SUPER::append_line( @_ );
   }
}

sub set_typing_line
{
   my $self = shift;
   my ( $line ) = @_;

   $self->{scroller}->pop if delete $self->{typing_line};

   # No timestamp
   local $self->{timestamp_format};
   $self->SUPER::append_line( $self->{typing_line} = $line ) if $line;
}

sub still_typing
{
   my $self = shift;

   my $timer = $self->{typing_grace_timer};
   if( $timer->is_running ) {
      $timer->reset;
   }
   else {
      $self->{room}->typing_start;
      $timer->start;
   }
}

sub update_headline
{
   my $self = shift;
   my $room = $self->{room};

   $self->{headline}->set_text( $room->topic // "" );
}

sub update_member_presence
{
   my $self = shift;
   my ( $member ) = @_;

   return; # TODO

   my $user = $member->user;
   my $user_id = $user->user_id;

   my $presence_userids = $self->{presence_userids};

   # Find an existing row if we can
   my $rowidx;
   $presence_userids->[$_] eq $user_id and $rowidx = $_, last
      for 0 .. $#$presence_userids;

   my $presence_table = $self->{presence_table};

   if( defined $rowidx and !defined $member->membership ) {
      splice @$presence_userids, $rowidx, 1, ();
      $presence_table->delete_row( $rowidx+1 );
      return;
   }

   my ( $w_name, $w_since, $w_power );
   if( defined $rowidx ) {
      ( $w_name, $w_since, $w_power ) = $presence_table->get_row( $rowidx+1 );
   }
   else {
      $presence_table->append_row( [
         $w_name  = Tickit::Widget::Static->new( text => "" ),
         $w_since = Tickit::Widget::Static->new( text => "" ),
         $w_power = Tickit::Widget::Static->new( text => "-", class => "level" ),
      ] );
      push @$presence_userids, $user_id;
   }

   $w_name->set_style( fg => $PRESENCE_STATE_TO_COLOUR{$user->presence} )
      if defined $user->presence;

   my $dname = defined $member->displayname ? $member->displayname : "[".$user->user_id."]";
   $dname = substr( $dname, 0, 17 ) . "..." if length $dname > 20;
   $w_name->set_text( $dname );

   if( defined $user->last_active ) {
      $w_since->set_text( strftime "%Y/%m/%d %H:%M", localtime $user->last_active );
   }
   else {



( run in 0.814 second using v1.01-cache-2.11-cpan-7e98afdb40f )