Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,19 @@ import {
ReactiveFormsModule,
UntypedFormBuilder,
UntypedFormGroup,
Validators,
Validators
} from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { firstValueFrom } from 'rxjs';
import { Playlist } from '../../../../../shared/playlist.interface';
import { DataService } from '../../../services/data.service';
import { PlaylistsService } from '../../../services/playlists.service';
import { PlaylistMeta } from '../../../shared/playlist-meta.type';
import * as PlaylistActions from '../../../state/actions';

Expand All @@ -26,6 +29,7 @@ import * as PlaylistActions from '../../../state/actions';
imports: [
TranslateModule,
MatButtonModule,
MatIconModule,
MatInputModule,
MatCheckboxModule,
CommonModule,
Expand All @@ -49,6 +53,7 @@ export class PlaylistInfoComponent {
private formBuilder: UntypedFormBuilder,
private dataService: DataService,
@Inject(MAT_DIALOG_DATA) playlist: Playlist,
private playlistService: PlaylistsService,
private store: Store
) {
this.playlist = playlist;
Expand Down Expand Up @@ -89,4 +94,21 @@ export class PlaylistInfoComponent {
saveChanges(playlist: PlaylistMeta): void {
this.store.dispatch(PlaylistActions.updatePlaylistMeta({ playlist }));
}

async exportPlaylist() {
const playlistAsString = await firstValueFrom(
this.playlistService.getRawPlaylistById(this.playlist._id)
);
const element = document.createElement('a');
element.setAttribute(
'href',
'data:text/plain;charset=utf-8,' +
encodeURIComponent(playlistAsString)
);
element.setAttribute('download', this.playlist.title || 'exported.m3u');
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
}
11 changes: 9 additions & 2 deletions src/app/services/playlists.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { Channel } from '../../../shared/channel.interface';
import { GLOBAL_FAVORITES_PLAYLIST_ID } from '../../../shared/constants';
import {
Playlist,
PlaylistUpdateState,
PlaylistUpdateState
} from '../../../shared/playlist.interface';
import {
aggregateFavoriteChannels,
createFavoritesPlaylist,
createPlaylistObject,
createPlaylistObject
} from '../../../shared/playlist.utils';
import { DbStores } from '../indexed-db.config';
import { PlaylistMeta } from '../shared/playlist-meta.type';
Expand Down Expand Up @@ -191,4 +191,11 @@ export class PlaylistsService {
)
);
}

getRawPlaylistById(id: string) {
return this.dbService.getByID<Playlist>(DbStores.Playlists, id).pipe(map(playlist => {
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
return playlist.playlist.header.raw + '\n' + playlist.playlist.items.map(item => item.raw).join('\n');
}));
}
}
3 changes: 2 additions & 1 deletion src/assets/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
"UPDATE_FAILED": "Update fehlgeschlagen",
"AUTO_UPDATE": "Auto-update",
"AUTO_UPDATE_DESCRIPTION": "Wenn die Auto-Refresh-Funktion aktiviert ist, wird die Wiedergabeliste bei jedem Start der Anwendung automatisch aktualisiert.",
"CUSTOM_USER_AGENT": "Einige IPTV-Anbieter benötigen einen bestimmten 'User-Agent', um ihre Playlist abspielen zu können."
"CUSTOM_USER_AGENT": "Einige IPTV-Anbieter benötigen einen bestimmten 'User-Agent', um ihre Playlist abspielen zu können.",
"EXPORT_PLAYLIST": "Als m3u exportieren"
},
"UPDATED": "Aktualisiert am",
"REFRESH": "Aktualisieren",
Expand Down
3 changes: 2 additions & 1 deletion src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"UPDATE_FAILED": "Last playlist update failed",
"AUTO_UPDATE": "Auto-update",
"AUTO_UPDATE_DESCRIPTION": "If the auto-refresh function is activated, the playlist will be updated automatically each time the app is started.",
"CUSTOM_USER_AGENT": "Some IPTV providers need a specific user-agent in order to play their playlist."
"CUSTOM_USER_AGENT": "Some IPTV providers need a specific user-agent in order to play their playlist.",
"EXPORT_PLAYLIST": "Export playlist as m3u"
},
"REMOVE_DIALOG": {
"TITLE": "Remove playlist",
Expand Down
3 changes: 2 additions & 1 deletion src/assets/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"UPDATE_FAILED": "Не удалось обновить плейлист",
"AUTO_UPDATE": "Автообновление",
"AUTO_UPDATE_DESCRIPTION": "Если активирована функция автообновления, список воспроизведения будет обновляться автоматически при каждом запуске приложения.",
"CUSTOM_USER_AGENT": "Некоторые IPTV провайдеры требуют указанние определенного пользовательского агента (User Agent) для воспроизведения своего плейлиста."
"CUSTOM_USER_AGENT": "Некоторые IPTV провайдеры требуют указанние определенного пользовательского агента (User Agent) для воспроизведения своего плейлиста.",
"EXPORT_PLAYLIST": "Экспортировать плейлист (m3u)"
},
"UPDATED": "Обновлен",
"REFRESH": "Обновить плейлист",
Expand Down