Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"modules": {
"invalid": {
"title": "#Error#"
},
"youtube": {
"title": "Vídeos informativos"
}
},
"module_group": {
Expand All @@ -16,6 +19,9 @@
},
"utilities": {
"title": "Utilidades"
},
"midias_online": {
"title": "Medios Online"
}
},
"components": {
Expand All @@ -41,4 +47,4 @@
"error_import_module": "Error al importar el módulo",
"misconfigured_module": "Este módulo está mal configurado. ¡La identificación ingresada en manifest.json debe tener el mismo nombre que la carpeta donde se encuentra!"
}
}
}
6 changes: 6 additions & 0 deletions src/lang/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"modules": {
"invalid": {
"title": "#Erro#"
},
"youtube": {
"title": "Momentos Missionários"
}
},
"module_group": {
Expand All @@ -16,6 +19,9 @@
},
"utilities": {
"title": "Utilitários"
},
"midias_online": {
"title": "Mídias Online"
}
},
"components": {
Expand Down
40 changes: 40 additions & 0 deletions src/modules/youtube/config/playlists.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"playlists": [
{
"id": "prova_e_vede_com_libras",
"name": "Prova e Vede - Com Libras",
"icon": "mdi-book-open-page-variant",
"color": "blue",
"type": "playlist",
"playlistId": "PLRzhXS-xO9iExRwxSXUF9t4skBu3f7cZE",
"url": "https://www.youtube.com/playlist?list=PLRzhXS-xO9iExRwxSXUF9t4skBu3f7cZE"
},
{
"id": "prova_e_vede",
"name": "Prova e Vede",
"icon": "mdi-cross",
"color": "indigo",
"type": "playlist",
"playlistId": "PLRzhXS-xO9iGgK8_6fX1hF1U5H4S9HJge",
"url": "https://www.youtube.com/playlist?list=PLRzhXS-xO9iGgK8_6fX1hF1U5H4S9HJge"
},
{
"id": "informativo_missoes",
"name": "Informativo Mundial das Missões",
"icon": "mdi-earth",
"color": "green",
"type": "playlist",
"playlistId": "PL_GfLCIoktxXUrnxifx8lGSdBxXR4gWLH",
"url": "https://www.youtube.com/playlist?list=PL_GfLCIoktxXUrnxifx8lGSdBxXR4gWLH"
},
{
"id": "minutos_saudade",
"name": "Minutos de Saudade",
"icon": "mdi-heart",
"color": "red",
"type": "playlist",
"playlistId": "PLTXME2yWP8A8UJO12bsCQ0pZCF3OL4k2U",
"url": "https://www.youtube.com/playlist?list=PLTXME2yWP8A8UJO12bsCQ0pZCF3OL4k2U"
}
]
}
18 changes: 18 additions & 0 deletions src/modules/youtube/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import BaseModule from "../BaseModule";
import es from "./lang/es.json";
import pt from "./lang/pt.json";
import manifest from "./manifest.json";

export default class extends BaseModule {
constructor() {
// Load translations
manifest.translations = { pt, es };

// Load manifest
super(manifest);
}

onInstall() {
console.log(`${this.manifest.name} installed successfully`);
}
}
178 changes: 178 additions & 0 deletions src/modules/youtube/interface/Index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
<template>
<ModuleContainer ref="moduleContainer" :manifest="manifest">
<template v-slot:header>
<v-toolbar>
<v-toolbar-title>
<v-icon start color="red">mdi-youtube</v-icon>
YouTube
</v-toolbar-title>
<v-spacer />
</v-toolbar>
</template>

<v-container fluid>
<v-row>
<!-- Categorias / Playlists -->
<v-col cols="12" md="3">
<v-card class="mb-4">
<v-card-title>
<v-icon start>mdi-playlist-play</v-icon>
{{ t('playlists') }}
</v-card-title>
<v-list>
<v-list-item
v-for="playlist in playlists"
:key="playlist.id"
:active="selectedPlaylist === playlist.id"
@click="selectPlaylist(playlist.id)"
link
>
<template v-slot:prepend>
<v-icon :color="playlist.color">{{ playlist.icon }}</v-icon>
</template>
<v-list-item-title>{{ playlist.name }}</v-list-item-title>
</v-list-item>
</v-list>
</v-card>
</v-col>

<!-- Lista de vídeos / Player -->
<v-col cols="12" md="9">
<v-card>
<v-card-title class="d-flex align-center">
<v-icon start :color="selectedPlaylistData?.color || 'red'">
{{ selectedPlaylistData?.icon || 'mdi-youtube' }}
</v-icon>
{{ selectedPlaylistTitle }}
<v-spacer />
<v-chip color="red" size="small">
{{ t('videos') }}
</v-chip>
</v-card-title>

<v-card-text>
<!-- Player de Playlist do YouTube -->
<div class="playlist-player-container">
<iframe
:src="currentEmbedUrl"
class="playlist-player-iframe"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>

<!-- Link para abrir no YouTube -->
<div class="text-center mt-4">
<v-btn
color="red"
variant="outlined"
:href="currentPlaylistUrl"
target="_blank"
>
<v-icon start>mdi-open-in-new</v-icon>
{{ t('open_in_youtube') }}
</v-btn>
</div>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-container>
</ModuleContainer>
</template>

<script>
import playlistsConfig from "../config/playlists.json";

export default {
name: "YouTubeIndex",
data: () => ({
playlists: playlistsConfig.playlists,
}),
computed: {
selectedPlaylist: {
get() {
return this.$appdata.get("modules.youtube.selectedPlaylist") || "prova_e_vede_com_libras";
},
set(value) {
this.$appdata.set("modules.youtube.selectedPlaylist", value);
}
},
selectedPlaylistTitle() {
const playlist = this.playlists.find(p => p.id === this.selectedPlaylist);
return playlist ? playlist.name : this.t('all_videos');
},
selectedPlaylistData() {
return this.playlists.find(p => p.id === this.selectedPlaylist);
},
currentEmbedUrl() {
const playlist = this.selectedPlaylistData;
if (!playlist) return "";

if (playlist.type === "playlist" && playlist.playlistId) {
return `https://www.youtube.com/embed/videoseries?list=${playlist.playlistId}`;
} else if (playlist.type === "channel") {
return `https://www.youtube.com/embed?listType=user_uploads&list=${playlist.url.split('@')[1]?.split('/')[0] || ''}`;
}
return "";
},
currentPlaylistUrl() {
const playlist = this.selectedPlaylistData;
if (!playlist) return "#";

if (playlist.type === "playlist" && playlist.playlistId) {
return `https://www.youtube.com/playlist?list=${playlist.playlistId}`;
} else if (playlist.url) {
return playlist.url;
}
return "#";
},
},
mounted() {
if (!this.$appdata.exists("modules.youtube.selectedPlaylist")) {
this.$appdata.set("modules.youtube.selectedPlaylist", "prova_e_vede_com_libras");
}
},
methods: {
t(text) {
return this.$t(`modules.youtube.${text}`);
},
selectPlaylist(playlistId) {
this.selectedPlaylist = playlistId;
},
},
};
</script>

<!-- ########################################################### -->
<!-- ####### SETUP OBRIGATÓRIA PARA INSTALAÇÃO DO MODULO ####### -->
<!-- ########################################################### -->
<script setup>
import manifest from "../manifest.json";
import ModuleContainer from "@/layout/ModuleContainer.vue";
import { ref } from "vue";
const moduleContainer = ref(null);
</script>
<!-- ########################################################### -->
<!-- ########################################################### -->
<!-- ########################################################### -->

<style scoped>
.playlist-player-container {
position: relative;
width: 100%;
padding-top: 56.25%;
background: #000;
border-radius: 8px;
overflow: hidden;
}

.playlist-player-iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
35 changes: 35 additions & 0 deletions src/modules/youtube/lang/es.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"title": "Vídeos informativos",
"name": "Vídeos informativos",
"description": "Integración con YouTube para reproducción de videos - Prueba y Ve, Informativo Mundial de las Misiones, Minutos de Saudade",
"search": "Buscar video",
"search_placeholder": "Escribe para buscar en YouTube...",
"playlists": "Listas de reproducción",
"videos": "Videos",
"now_playing": "Reproduciendo ahora",
"no_videos": "Ningún video encontrado",
"loading": "Cargando...",
"error_loading": "Error al cargar videos",
"prova_e_vede_com_libras": "Prueba y Ve - Con Libras",
"prova_e_vede": "Prueba y Ve",
"informativo_missões": "Informativo Mundial de las Misiones",
"minutos_saudade": "Minutos de Saudade",
"categories": "Categorías",
"all_videos": "Todos los Videos",
"add_to_queue": "Añadir a la cola",
"play_now": "Reproducir ahora",
"queue": "Cola de reproducción",
"clear_queue": "Limpiar cola",
"fullscreen": "Pantalla completa",
"exit_fullscreen": "Salir de pantalla completa",
"volume": "Volumen",
"mute": "Silenciar",
"unmute": "Activar sonido",
"settings": "Configuración",
"quality": "Calidad",
"speed": "Velocidad",
"normal": "Normal",
"autoplay": "Reproducción automática",
"related_videos": "Videos relacionados",
"open_in_youtube": "Abrir en YouTube"
}
37 changes: 37 additions & 0 deletions src/modules/youtube/lang/pt.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"title": "Vídeos informativos",
"name": "Vídeos informativos",
"description": "Integração com YouTube para reprodução de vídeos - Prova e Vede, Informativo Mundial das Missões, Minutos de Saudade",
"search": "Buscar vídeo",
"search_placeholder": "Digite para buscar no YouTube...",
"playlists": "Playlists",
"videos": "Vídeos",
"now_playing": "Reproduzindo agora",
"no_videos": "Nenhum vídeo encontrado",
"loading": "Carregando...",
"error_loading": "Erro ao carregar vídeos",
"prova_e_vede_com_libras": "Prova e Vede - Com Libras",
"prova_e_vede": "Prova e Vede",
"informativo_missões": "Informativo Mundial das Missões",
"minutos_saudade": "Minutos de Saudade",
"categories": "Categorias",
"all_videos": "Todos os Vídeos",
"add_to_queue": "Adicionar à fila",
"play_now": "Reproduzir agora",
"queue": "Fila de reprodução",
"clear_queue": "Limpar fila",
"fullscreen": "Tela cheia",
"exit_fullscreen": "Sair da tela cheia",
"volume": "Volume",
"mute": "Silenciar",
"unmute": "Ativar som",
"settings": "Configurações",
"quality": "Qualidade",
"speed": "Velocidade",
"normal": "Normal",
"autoplay": "Reprodução automática",
"related_videos": "Vídeos relacionados",
"open_in_youtube": "Abrir no YouTube",
"total_time": "Tempo total",
"time_remaining": "restante"
}
13 changes: 13 additions & 0 deletions src/modules/youtube/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"id": "youtube",
"name": "Vídeos informativos",
"version": "1.0.0",
"description": "Integração com YouTube para reprodução de vídeos - Prova e Vede, Informativo Mundial das Missões, Minutos de Saudade",
"author": "LouvorJA",
"category": "midias_online",
"icon": "mdi-youtube",
"showInMainMenu": true,
"minAppVersion": "1.0.0",
"dependencies": [],
"permissions": ["network"]
}
4 changes: 4 additions & 0 deletions src/store/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export default {
title: "module_group.utilities.title",
modules: [],
},
midias_online: {
title: "module_group.midias_online.title",
modules: [],
},
},
menu: {
show: false,
Expand Down