Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git
<?php
require_once __DIR__ . '/FileRenderer.php';
require_once __DIR__ . '/Highlighter.php';

class HtmlFileRenderer implements FileRenderer {
  private string $repoSafeName;
  private string $currentPath;

  public function __construct( string $repoSafeName, string $currentPath = '' ) {
    $this->repoSafeName = $repoSafeName;
    $this->currentPath = trim( $currentPath, '/' );
  }

  public function renderListEntry(
    string $name,
    string $sha,
    string $mode,
    string $iconClass,
    int $timestamp,
    int $size
  ): void {
    $fullPath = ($this->currentPath === '' ? '' : $this->currentPath . '/') .
      $name;

    $url = '?repo=' . urlencode( $this->repoSafeName ) .
           '&hash=' . $sha .
           '&name=' . urlencode( $fullPath );

    echo '<a href="' . $url . '" class="file-item">';
    echo '<span class="file-mode">' . $mode . '</span>';
    echo '<span class="file-name">';
    echo '<i class="fas ' . $iconClass . ' file-icon-container"></i>';
    echo htmlspecialchars( $name );
    echo '</span>';

    if( $size > 0 ) {
      echo '<span class="file-size">' . $this->formatSize( $size ) . '</span>';
    }

    if( $timestamp > 0 ) {
      echo '<span class="file-date">';
      $this->renderTime( $timestamp );
      echo '</span>';
    }

    echo '</a>';
  }

  public function renderMedia(
    File $file,
    string $url,
    string $mediaType
  ): bool {
    $rendered = false;

    if( $file->isImage() ) {
      echo '<div class="blob-content blob-content-image">' .
        '<img src="' . $url . '"></div>';
      $rendered = true;
    } elseif( $file->isVideo() ) {
      echo '<div class="blob-content blob-content-video">' .
        '<video controls><source src="' . $url . '" type="' .
        $mediaType . '"></video></div>';
      $rendered = true;
    } elseif( $file->isAudio() ) {
      echo '<div class="blob-content blob-content-audio">' .
        '<audio controls><source src="' . $url . '" type="' .
        $mediaType . '"></audio></div>';
      $rendered = true;
    }

    return $rendered;
  }

  public function renderSize( int $bytes ): void {
    echo $this->formatSize( $bytes );
  }

  public function highlight(
    string $filename,
    string $content,
    string $mediaType
  ): string {
    return (new Highlighter($filename, $content, $mediaType))->render();
  }

  public function renderTime( int $timestamp ): void {
    $tokens = [
      31536000 => 'year',
      2592000 => 'month',
      604800 => 'week',
      86400 => 'day',
      3600 => 'hour',
      60 => 'minute',
      1 => 'second'
    ];

    $diff = $timestamp ? time() - $timestamp : null;
    $result = 'never';

    if( $diff && $diff >= 5 ) {
      foreach( $tokens as $unit => $text ) {
        if( $diff < $unit ) {
          continue;
        }

        $num = floor( $diff / $unit );
        $result = $num . ' ' . $text . ($num > 1 ? 's' : '') . ' ago';
        break;
      }
    } elseif( $diff ) {
      $result = 'just now';
    }

    echo $result;
  }

  private function formatSize( int $bytes ): string {
    $units = [ 'B', 'KB', 'MB', 'GB', 'TB' ];
    $i = 0;

    while( $bytes >= 1024 && $i < count( $units ) - 1 ) {
      $bytes /= 1024;
      $i++;
    }

    return ($bytes === 0 ? 0 : round( $bytes )) . ' ' . $units[$i];
  }
}