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
201 changes: 148 additions & 53 deletions src/components/AddonItem.vue
Original file line number Diff line number Diff line change
@@ -1,57 +1,57 @@
<script setup>
const props = defineProps({
name: {
type: String,
required: true
},
idx: {
type: Number,
required: true
},
manifestURL: {
type: String,
required: true
},
logoURL: {
type: String,
required: false
},
isDeletable: {
type: Boolean,
required: false,
default: true
},
isConfigurable: {
type: Boolean,
required: false,
default: false
}
})

const emits = defineEmits(['delete-addon'])



const defaultLogo = 'https://icongr.am/feather/box.svg?size=48&color=ffffff'


function copyManifestURLToClipboard() {
navigator.clipboard.writeText(props.manifestURL).then(() => {
console.log('Text copied to clipboard')
}).catch((error) => {
console.error('Error copying text to clipboard', error)
const props = defineProps({
name: {
type: String,
required: true
},
idx: {
type: Number,
required: true
},
manifestURL: {
type: String,
required: true
},
logoURL: {
type: String,
required: false
},
isDeletable: {
type: Boolean,
required: false,
default: true
},
isConfigurable: {
type: Boolean,
required: false,
default: false
}
})
}

function openAddonConfigurationPage() {
const configureURL = props.manifestURL.replace("stremio://", "https://").replace("/manifest.json", "/configure");
window.open(configureURL);
}

function removeAddon() {
emits('delete-addon', props.idx)
}


const emits = defineEmits(['delete-addon', 'edit-manifest'])

const defaultLogo = 'https://icongr.am/feather/box.svg?size=48&color=ffffff'

function copyManifestURLToClipboard() {
navigator.clipboard.writeText(props.manifestURL).then(() => {
console.log('Text copied to clipboard')
}).catch((error) => {
console.error('Error copying text to clipboard', error)
})
}

function openAddonConfigurationPage() {
const configureURL = props.manifestURL.replace("stremio://", "https://").replace("/manifest.json", "/configure");
window.open(configureURL);
}

function removeAddon() {
emits('delete-addon', props.idx)
}

function openEditManifestModal() {
emits('edit-manifest', props.idx)
}
</script>

<template>
Expand All @@ -73,6 +73,9 @@ function removeAddon() {
@click="copyManifestURLToClipboard">
<img src="https://icongr.am/feather/clipboard.svg?size=12">
</button>
<button class="button icon-only edit-manifest" title="Edit manifest JSON" @click="openEditManifestModal">
<img src="https://icongr.am/feather/edit.svg?size=12">
</button>
<button class="button icon-only delete" title="Remove addon from list" :disabled="!isDeletable"
@click="removeAddon">
<img src="https://icongr.am/feather/trash-2.svg?size=12">
Expand All @@ -91,9 +94,9 @@ function removeAddon() {
border-radius: 5px;
padding: 10px 13px;
margin-bottom: 11px;
/* box-shadow: 0 2px 4px rgba(0,0,0,0.06); */
border: 1px solid #ccc;
justify-content: space-between;
flex-wrap: wrap;
}

.dark .sortable-list .item {
Expand All @@ -103,6 +106,7 @@ function removeAddon() {
.item .details {
display: flex;
align-items: center;
flex: 1;
}

.item .details img {
Expand All @@ -114,6 +118,97 @@ function removeAddon() {
object-position: center;
border-radius: 30%;
background-color: #262626;
}

.col {
display: flex;
gap: 8px;
flex-wrap: wrap;
align-items: center;
min-width: 200px;
}

.button {
border-radius: 4px;
cursor: pointer;
padding: 5px;
transition: background-color 0.3s;
}

.icon-only {
display: flex;
justify-content: center;
align-items: center;
}

.visit-url img,
.copy-url img,
.edit-manifest img,
.delete img {
width: 20px;
height: 20px;
}

@media (max-width: 768px) {
.sortable-list .item {
flex-direction: column;
align-items: center;
padding: 10px;
}

.item .details {
margin-bottom: 10px;
text-align: center;
}

.item .details img {
margin-right: 12px;
margin-bottom: 8px;
}

.col {
flex-direction: row;
gap: 8px;
justify-content: center;
width: 100%;
margin-top: 10px;
}

.button {
padding: 6px;
}

.uil-draggabledots {
position: absolute;
right: 10px;
bottom: 10px;
}
}

@media (max-width: 480px) {
.item .details {
flex-direction: column;
align-items: center;
text-align: center;
}

.item .details img {
margin-bottom: 6px;
}

.col {
flex-direction: row;
gap: 4px;
justify-content: center;
width: 100%;
}

.button {
padding: 4px;
}

.uil-draggabledots {
display: none;
}
}
</style>
76 changes: 73 additions & 3 deletions src/components/Configuration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import { ref } from 'vue'
import draggable from 'vuedraggable'
import AddonItem from './AddonItem.vue'
import Authentication from './Authentication.vue'
import DynamicForm from './DynamicForm.vue'

const stremioAPIBase = "https://api.strem.io/api/"
const dragging = false
let stremioAuthKey = ref('');
let addons = ref([])
let loadAddonsButtonText = ref('Load Addons')

let isEditModalVisible = ref(false);
let currentManifest = ref({});
let currentEditIdx = ref(null);

function loadUserAddons() {
const key = stremioAuthKey.value
if (!key) {
Expand Down Expand Up @@ -97,7 +102,28 @@ function setAuthKey(authKey) {
console.log('AuthKey set to: ', stremioAuthKey.value)
}

function openEditModal(idx) {
isEditModalVisible.value = true;
currentEditIdx.value = idx;
currentManifest.value = { ...addons.value[idx].manifest };
document.body.classList.add('modal-open');
}

function closeEditModal() {
isEditModalVisible.value = false;
currentManifest.value = {};
currentEditIdx.value = null;
document.body.classList.remove('modal-open');
}

function saveManifestEdit(updatedManifest) {
try {
addons.value[currentEditIdx.value].manifest = updatedManifest;
closeEditModal();
} catch (e) {
alert('Failed to update manifest');
}
}
</script>

<template>
Expand All @@ -122,7 +148,8 @@ function setAuthKey(authKey) {
:logoURL="element.manifest.logo"
:isDeletable="!getNestedObjectProperty(element, 'flags.protected', false)"
:isConfigurable="getNestedObjectProperty(element, 'manifest.behaviorHints.configurable', false)"
@delete-addon="removeAddon" />
@delete-addon="removeAddon"
@edit-manifest="openEditModal" />
</template>
</draggable>
</fieldset>
Expand All @@ -133,12 +160,17 @@ function setAuthKey(authKey) {
</button>
</fieldset>
</form>

</section>

<div v-if="isEditModalVisible" class="modal" @click.self="closeEditModal">
<div class="modal-content">
<h3>Edit manifest</h3>
<DynamicForm :manifest="currentManifest" @update-manifest="saveManifestEdit" />
</div>
</div>
</template>

<style scoped>
/* sortable list/addon list specifics */
.sortable-list {
padding: 25px;
border-radius: 7px;
Expand All @@ -153,4 +185,42 @@ function setAuthKey(authKey) {
.item.dragging :where(.details, i) {
opacity: 0;
}

.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
overflow: auto;
}

.modal-content {
background: #2e2e2e;
color: #e0e0e0;
width: 75vw;
max-width: 900px;
max-height: 90vh;
padding: 20px;
border-radius: 5px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.7);
overflow: hidden;
display: flex;
flex-direction: column;
}

button {
padding: 10px 20px;
border: none;
background-color: #ffa600;
color: white;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
}
</style>
Loading