extention-updater / index.html
dwirafastd's picture
undefined - Initial Deployment
91de28f verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Extension Updater Tool</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.drag-area {
border: 2px dashed #ccc;
transition: all 0.3s ease;
}
.drag-area.active {
border-color: #4f46e5;
background-color: #eef2ff;
}
.feature-card {
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.feature-card:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
.progress-bar {
transition: width 0.5s ease;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.pulse {
animation: pulse 2s infinite;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<header class="mb-8 text-center">
<h1 class="text-3xl md:text-4xl font-bold text-indigo-700 mb-2">Extension Updater</h1>
<p class="text-gray-600 max-w-2xl mx-auto">Analyze and incorporate features from other extensions into your own</p>
</header>
<!-- Main Content -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Panel - Upload and Analyze -->
<div class="lg:col-span-2 space-y-6">
<!-- Upload Section -->
<div class="bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Upload Extension Data</h2>
<div class="drag-area border-2 border-dashed rounded-lg p-8 text-center cursor-pointer mb-4"
id="dropZone">
<div class="icon text-indigo-500 mb-3">
<i class="fas fa-cloud-upload-alt text-4xl"></i>
</div>
<header class="font-medium text-gray-700">Drag & Drop to Upload</header>
<span class="text-gray-500 block my-2">or</span>
<button class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 transition">
Browse Files
</button>
<input type="file" id="fileInput" class="hidden" accept=".json,.zip,.crx" multiple>
</div>
<div class="flex flex-wrap gap-2 mb-4">
<span class="bg-indigo-100 text-indigo-800 px-3 py-1 rounded-full text-sm">.json</span>
<span class="bg-indigo-100 text-indigo-800 px-3 py-1 rounded-full text-sm">.zip</span>
<span class="bg-indigo-100 text-indigo-800 px-3 py-1 rounded-full text-sm">.crx</span>
</div>
</div>
<!-- Analysis Results -->
<div class="bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Analysis Results</h2>
<div class="space-y-4" id="analysisResults">
<div class="p-4 bg-gray-100 rounded-lg text-center text-gray-500">
<i class="fas fa-microscope text-2xl mb-2"></i>
<p>Upload extension files to begin analysis</p>
</div>
</div>
</div>
</div>
<!-- Right Panel - Your Extension -->
<div class="space-y-6">
<!-- Your Extension Info -->
<div class="bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Your Extension</h2>
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mr-3">
<i class="fas fa-puzzle-piece text-indigo-600 text-xl"></i>
</div>
<div>
<h3 class="font-medium" id="extensionName">My Awesome Extension</h3>
<p class="text-sm text-gray-500" id="extensionVersion">v1.0.0</p>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-1">Version</label>
<input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" id="versionInput" value="1.0.0">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-1">Description</label>
<textarea class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" rows="3" id="descriptionInput">My custom browser extension</textarea>
</div>
</div>
<!-- Update Progress -->
<div class="bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Update Progress</h2>
<div class="mb-4">
<div class="flex justify-between text-sm text-gray-600 mb-1">
<span>Update Status</span>
<span id="progressPercent">0%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2.5">
<div class="progress-bar bg-indigo-600 h-2.5 rounded-full" style="width: 0%" id="progressBar"></div>
</div>
</div>
<button class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition flex items-center justify-center gap-2 disabled:opacity-50" id="updateButton" disabled>
<i class="fas fa-sync-alt"></i>
<span>Update Extension</span>
</button>
<div class="mt-4 text-sm text-gray-500 hidden" id="updateMessage">
<i class="fas fa-info-circle mr-1"></i>
<span id="messageText"></span>
</div>
</div>
</div>
</div>
<!-- Feature Comparison -->
<div class="mt-8 bg-white rounded-xl shadow-md p-6">
<h2 class="text-xl font-semibold text-gray-800 mb-4">Feature Comparison</h2>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Feature</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Source Extension</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Your Extension</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Action</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="featureTable">
<tr>
<td colspan="4" class="px-6 py-4 text-center text-gray-500">
Upload files to compare features
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const analysisResults = document.getElementById('analysisResults');
const featureTable = document.getElementById('featureTable');
const updateButton = document.getElementById('updateButton');
const progressBar = document.getElementById('progressBar');
const progressPercent = document.getElementById('progressPercent');
const updateMessage = document.getElementById('updateMessage');
const messageText = document.getElementById('messageText');
// Drag and drop functionality
dropZone.addEventListener('click', () => fileInput.click());
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
dropZone.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, unhighlight, false);
});
function highlight() {
dropZone.classList.add('active');
}
function unhighlight() {
dropZone.classList.remove('active');
}
dropZone.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles(files);
}
fileInput.addEventListener('change', function() {
handleFiles(this.files);
});
function handleFiles(files) {
if (files.length === 0) return;
// Simulate analysis (in a real app, you would process the files)
analysisResults.innerHTML = `
<div class="p-4 bg-blue-50 rounded-lg flex items-start">
<div class="mr-3 text-blue-500">
<i class="fas fa-spinner fa-spin text-xl"></i>
</div>
<div>
<h3 class="font-medium text-blue-800">Analyzing ${files.length} file(s)...</h3>
<p class="text-sm text-blue-600">This may take a few moments</p>
</div>
</div>
`;
setTimeout(() => {
showAnalysisResults(files);
updateButton.disabled = false;
}, 2000);
}
function showAnalysisResults(files) {
// Mock data - in a real app this would come from actual analysis
const mockFeatures = [
{
name: "Dark Mode",
description: "Adds dark theme support",
sourceHas: true,
yourHas: false,
compatible: true
},
{
name: "Keyboard Shortcuts",
description: "Customizable keyboard commands",
sourceHas: true,
yourHas: true,
compatible: true
},
{
name: "Data Export",
description: "Export extension data to JSON",
sourceHas: true,
yourHas: false,
compatible: true
},
{
name: "Cloud Sync",
description: "Sync settings across devices",
sourceHas: true,
yourHas: false,
compatible: false,
reason: "Requires backend service"
}
];
// Update analysis results
analysisResults.innerHTML = `
<div class="p-4 bg-green-50 rounded-lg mb-4">
<div class="flex items-center justify-between mb-2">
<h3 class="font-medium text-green-800">Analysis Complete</h3>
<span class="bg-green-100 text-green-800 px-2 py-1 rounded-full text-xs">${files.length} file(s)</span>
</div>
<p class="text-sm text-green-600 mb-3">Found ${mockFeatures.length} features to analyze</p>
<div class="flex flex-wrap gap-2">
<span class="bg-green-100 text-green-800 px-2 py-1 rounded-full text-xs">${mockFeatures.filter(f => f.compatible).length} compatible</span>
<span class="bg-yellow-100 text-yellow-800 px-2 py-1 rounded-full text-xs">${mockFeatures.filter(f => !f.compatible).length} incompatible</span>
</div>
</div>
`;
// Update feature comparison table
featureTable.innerHTML = mockFeatures.map(feature => `
<tr class="${feature.compatible ? '' : 'bg-gray-50'}">
<td class="px-6 py-4 whitespace-nowrap">
<div class="font-medium text-gray-900">${feature.name}</div>
<div class="text-sm text-gray-500">${feature.description}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
${feature.sourceHas ?
'<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">Available</span>' :
'<span class="px-2 py-1 bg-gray-100 text-gray-800 rounded-full text-xs">Not Available</span>'}
</td>
<td class="px-6 py-4 whitespace-nowrap">
${feature.yourHas ?
'<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">Available</span>' :
'<span class="px-2 py-1 bg-gray-100 text-gray-800 rounded-full text-xs">Not Available</span>'}
</td>
<td class="px-6 py-4 whitespace-nowrap">
${feature.compatible ?
(feature.yourHas ?
'<span class="text-sm text-gray-500">Already implemented</span>' :
'<button class="text-indigo-600 hover:text-indigo-900 text-sm font-medium add-feature" data-feature="${feature.name}">Add to extension</button>') :
`<span class="text-sm text-gray-500">Incompatible: ${feature.reason}</span>`}
</td>
</tr>
`).join('');
}
// Update button functionality
updateButton.addEventListener('click', function() {
updateButton.disabled = true;
updateButton.innerHTML = '<i class="fas fa-spinner fa-spin"></i><span>Updating...</span>';
// Simulate update progress
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 10;
if (progress > 100) progress = 100;
progressBar.style.width = `${progress}%`;
progressPercent.textContent = `${Math.round(progress)}%`;
if (progress === 100) {
clearInterval(interval);
updateComplete();
}
}, 300);
});
function updateComplete() {
updateButton.innerHTML = '<i class="fas fa-check"></i><span>Update Complete</span>';
updateButton.classList.remove('bg-indigo-600', 'hover:bg-indigo-700');
updateButton.classList.add('bg-green-600', 'hover:bg-green-700');
messageText.textContent = 'Extension updated successfully! New features have been added.';
updateMessage.classList.remove('hidden');
updateMessage.classList.add('text-green-500');
// Update version
const versionInput = document.getElementById('versionInput');
const currentVersion = versionInput.value.split('.');
currentVersion[1] = parseInt(currentVersion[1]) + 1;
versionInput.value = currentVersion.join('.');
// Change extension name to indicate update
const extensionName = document.getElementById('extensionName');
extensionName.textContent = "My Awesome Extension (Updated)";
}
// Feature addition (delegated event for dynamic elements)
document.addEventListener('click', function(e) {
if (e.target.classList.contains('add-feature')) {
const featureName = e.target.getAttribute('data-feature');
e.target.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Adding...';
e.target.disabled = true;
// Simulate adding feature
setTimeout(() => {
e.target.innerHTML = '<i class="fas fa-check"></i> Added';
e.target.classList.remove('text-indigo-600', 'hover:text-indigo-900');
e.target.classList.add('text-green-600');
// Update the "Your Extension" column
const row = e.target.closest('tr');
const yourExtensionCell = row.querySelector('td:nth-child(3)');
yourExtensionCell.innerHTML = '<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs">Available</span>';
}, 1500);
}
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=dwirafastd/extention-updater" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>