team113 / messenger

Open-source front-end part of messenger by team113
GNU Affero General Public License v3.0
16 stars 13 forks source link

[$250] Implement audio player for audio file attachments in `Chat` #618

Open SleepySquash opened 11 months ago

SleepySquash commented 11 months ago

Background

Messenger Gapopa. Chat page. Sent or received audio file.

Problem to solve

To do: display audio files as a player with audio playback option, cover with integration test.

Requirements:

Please note some stylistic differences in the solution on computer and on phone.

Possible solutions

PlayableAsset widget should be extended and redesigned for the needs described above. The remote file (FileAttachment) and the local file (LocalAttachment) should be able to be identified as audio to be displayed as a player in the attachment list.

Use the AudioUtils class to play the audio. It would make sense to have some field or method in this class that would ensure in some way that only one audio is played back.

For coverage with tests, it is suggested to write an AudioUtils mock, which will confirm that a call to the audio has been made through the appropriate steps.

oogxdd commented 5 months ago

Прошу пока не закрывать PR. Решил подойти к задаче в более широком ключе чтобы имплементить глобальный плеер потом. Вот план действий:

  1. /domain/models/audio_file.dart

    • AudioFile class:
      • id (String)
      • name (String)
      • source (AudioSource)
  2. /lib/store/audio_store.dart

    • AudioStore (extends GetxController) - high-level controller который предоставляет все необходимые методы для взаимодействия с плеером и унаследует low-level методы из AudioUtils:
      • State:
        • currentAudio (AudioFile)
        • playlistQueue (List)
        • playbackState (PlaybackState)
          • playing (bool)
          • processingState (ProcessingState: 'idle' | 'loading' | 'buffering' | 'ready' | 'completed')
          • bufferedPosition (Duration)
          • queueIndex - currently playing song index in the playlist
          • repeatMode
          • shuffleMode
          • ... and so on
        • currentSongPosition (Duration)
        • currentSongDuration (Duration)
      • Methods:
        • play(AudioFile audioFile): void - унаследовано из AudioUtils
        • pause(): void - унаследовано из AudioUtils
        • seek(Duration position): void - унаследовано из AudioUtils
        • setCurrentAudio(AudioFile audioFile): void
        • skipToNext(): void
        • skipToPrevious(): void
        • addQueueItem(AudioFile audioFile): void
        • removeQueueItemAt(AudioFile audioFile) void
  3. /lib/ui/widget/audio_bar.dart

    • AudioBar widget (subscribes to AudioStore):
      • Properties:
        • songTitle (AudioFile.title) - унаследовано из AudioStore
      • Methods:
        • play(AudioFile audioFile): void - унаследовано из AudioStore
        • pause(): void - унаследовано из AudioStore
  4. /ui/home/chat/widget/audio_attachment.dart

    • AudioAttachment widget:
      • Properties:
        • SendingStatus - унаследовано из LocalAttachment
        • DownloadStatus (bool) - унаследовано из Attachment
      • Methods:
        • play(AudioFile audioFile): void - унаследовано из AudioStore
        • pause(): void - унаследовано из AudioStore
        • seek(Duration position): void - унаследовано из AudioStore
      • UI:
        • Seekbar slider
        • Play/pause button
  5. /util/audio_utils.dart

    • AudioPlayer (uses Just-Audio package):
      • Properties:
        • player (ja.AudioPlayer)
        • queue (ja.ConcatenatingAudioSource)
        • currentPosition (Duration)
        • totalDuration (Duration)
      • Methods:
        • play(AudioSource audioSource): void
        • pause(): void
        • seek(Duration position): void

Далее добавить еще AudioPlaylistScreen (который будет показываться если кликаешь на AudioBar, где можно будет смотреть PlaylistQueue, делать rewind, переключать треки).

Также думаю о том чтобы использовать just-audio для аудио на всех платформах. Нам все равно придется учитывать кейсы когда юзер слушает аудио, потом открывает видео - чтобы аудио останавливалось на время когда юзер смотрит видео, а потом возобновлялось. И делать это для каждой платформы. Пока что не знаю, начну с того что сделаю все остальные компоненты и адаптирую AudioUtils для ja.AudioPlayer, а там предпримем решение

Это approximate draft. К завтрашнему дню планирую завершить часть просто с проигрыванием одного аудио только на странице чата. Потом, надеюсь, получится продолжить.

SleepySquash commented 5 months ago

@oogxdd, по структуре: в сторе лежит реализация домена, предметной области приложения. Я не уверен, что это репозиторий, вовсе. Скорее воркер, как тот же кэш. В модели AudioFile тоже пока не уверен, существуют же FileAttachmentы, хотя это сущности чата. Иначе их нужно будет маппить друг в друга. Может и ок, надо смотреть.

just_audio - это костыль для мобильных платформ, чтобы там через audio_session менялся динамик (media_kit кладёт одно место на попытку переключить внутренний/внешний/sco динамики). Ничто в теории не мешает написать абстракцию такую, чтобы уже её реализация была либо just_audio, либо media_kit - это была бы хорошая практика. Я бы предложил не отказываться от media_kit для аудио, т.к. он использует MPV, это довольно небольшой и лёгкий плеер.

Указанный Вами дедлайн - это сегодня. С учётом Вашего комментария, полагаю, дедлайн будет просрочен. Прошу сориентировать, пожалуйста, по срокам. И напоминаю про правила: https://gapopa.com/work/freelance. В #872 не было коммитов более 72-х часов.

oogxdd commented 5 months ago

Первый коммит запушил. Так пока все супер messy, прошу перенести дедлайн на понедельник. Постараюсь причесать все за выходные @SleepySquash

SleepySquash commented 5 months ago

@oogxdd, принял, хорошо.