Better Daymap

Customize your profile picture and background on Daymap.

Verze ze dne 27. 04. 2025. Zobrazit nejnovější verzi.

// ==UserScript==
// @name         Better Daymap
// @namespace    Better Daymap
// @version      2.0
// @description  Customize your profile picture and background on Daymap.
// @author       LiamGo
// @match        https://*.daymap.net/*
// @icon         https://lh3.googleusercontent.com/_Jt3LvQt0VV4wQkW6brDIvKNCQMSWgzbE_ofiwnWCgWTw4pUv4HsLX0AH8PpNEde85jt8XPWyXQo91d4MEYqZZgm-k4=s60
// @grant        GM_registerMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    // Configuration defaults
    const DEFAULTS = {
        backgroundColor: '#000000',
        backgroundImage: '',
        profileImage: '',
        disabledSections: {
            indicators: false,
            diaryNotes: false,
            homework: false,
            currentTasks: false,
            messages: false,
            bulletins: false,
            newsletters: false,
            rcFactSheets: false
        }
    };

    const SECTIONS = [
        { id: 'indicators',    name: 'Indicators',      selector: '#pnlMid > div.card.expWindow:nth-of-type(1)' },
        { id: 'diaryNotes',    name: 'My Diary Notes',  selector: '#pnlMid > div.card.expWindow:nth-of-type(2)' },
        { id: 'homework',      name: 'Homework',        selector: '#pnlMid > div.card.expWindow:nth-of-type(3)' },
        { id: 'currentTasks',  name: 'Current Tasks',   selector: '#pnlMid > div.card.expWindow:nth-of-type(4)' },
        { id: 'messages',      name: 'Messages',        selector: '#pnlRight > div.card.expWindow:nth-of-type(1)' },
        { id: 'bulletins',     name: 'Bulletins',       selector: '#pnlRight > div.card.expWindow:nth-of-type(2)' },
        { id: 'newsletters',   name: 'Newsletters',     selector: '#pnlRight > div.card.expWindow:nth-of-type(3)' },
        { id: 'rcFactSheets',  name: 'RC Fact Sheets',  selector: '#pnlRight > div.card.expWindow:nth-of-type(4)' }
    ];

    // Apply settings from storage
    function applySettings() {
        const bgColor = GM_getValue('backgroundColor', DEFAULTS.backgroundColor);
        const bgImage = GM_getValue('backgroundImage', DEFAULTS.backgroundImage);
        const profileImage = GM_getValue('profileImage', DEFAULTS.profileImage);
        const disabledSections = GM_getValue('disabledSections', DEFAULTS.disabledSections);

        document.body.style.backgroundColor = bgColor;

        if (bgImage) {
            document.body.style.backgroundImage = `url(${bgImage})`;
            document.body.style.backgroundSize = '100% 100%';
            document.body.style.backgroundRepeat = 'no-repeat';
            document.body.style.backgroundPosition = 'top left';
            document.body.style.backgroundAttachment = 'fixed';
        } else {
            document.body.style.backgroundImage = '';
        }

        if (profileImage) {
            setTimeout(() => {
                const avatarElements = [
                    document.querySelector('.nav-user-image'),
                    document.querySelector('.photoThumb')
                ];
                avatarElements.forEach(avatarElement => {
                    if (avatarElement) {
                        avatarElement.style.backgroundImage = `url(${profileImage})`;
                    }
                });
            }, 1750);
        }

        SECTIONS.forEach(section => {
            document.querySelectorAll(section.selector).forEach(el => {
                el.style.display = disabledSections[section.id] ? 'none' : '';
            });
        });
    }

    // Adjust the height of Current Tasks and Messages
    function expandContentHeight() {
        const currentTasks = document.querySelector('#pnlMid > div.card.expWindow:nth-of-type(4) .expContent');
        const messages = document.querySelector('#pnlRight > div.card.expWindow:nth-of-type(1) .expContent');

        if (currentTasks) {
            currentTasks.style.minHeight = '500px'; // Adjust this value if needed
        }
        if (messages) {
            messages.style.minHeight = '500px'; // Adjust this value if needed
        }
    }

    // Create settings UI
    function createSettingsPage() {
        const modal = document.createElement('div');
        modal.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 20px rgba(0,0,0,0.3);
            z-index: 9999;
            min-width: 400px;
            font-family: Arial, sans-serif;
        `;

        const heading = document.createElement('h2');
        heading.textContent = 'Better Daymap Settings';
        heading.style.marginTop = '0';

        const form = document.createElement('div');
        form.style.display = 'grid';
        form.style.gap = '15px';

        const colorLabel = createLabel('Background Color:', 'color');
        const colorInput = createInput('color', 'backgroundColor', GM_getValue('backgroundColor', DEFAULTS.backgroundColor));

        const bgImageLabel = createLabel('Background Image URL:', 'bgImage');
        const bgImageInput = createInput('text', 'bgImage', GM_getValue('backgroundImage', DEFAULTS.backgroundImage));
        bgImageInput.placeholder = 'https://example.com/image.jpg';

        const profileLabel = createLabel('Profile Image URL:', 'profile');
        const profileInput = createInput('text', 'profile', GM_getValue('profileImage', DEFAULTS.profileImage));
        profileInput.placeholder = 'https://example.com/avatar.jpg';

        const sectionLabel = document.createElement('div');
        sectionLabel.textContent = 'Disable Sections:';
        sectionLabel.style.fontWeight = 'bold';
        sectionLabel.style.marginTop = '15px';

        const togglesContainer = document.createElement('div');
        togglesContainer.style.display = 'flex';
        togglesContainer.style.gap = '20px';

        const leftColumn = document.createElement('div');
        leftColumn.style.display = 'flex';
        leftColumn.style.flexDirection = 'column';
        leftColumn.style.gap = '8px';

        const rightColumn = document.createElement('div');
        rightColumn.style.display = 'flex';
        rightColumn.style.flexDirection = 'column';
        rightColumn.style.gap = '8px';

        const disabledSections = GM_getValue('disabledSections', DEFAULTS.disabledSections);
        SECTIONS.forEach((section, index) => {
            const wrapper = document.createElement('div');
            wrapper.style.display = 'flex';
            wrapper.style.alignItems = 'center';
            wrapper.style.gap = '8px';

            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.id = `section-${section.id}`;
            checkbox.checked = disabledSections[section.id];

            const label = document.createElement('label');
            label.htmlFor = `section-${section.id}`;
            label.textContent = section.name;
            label.style.cursor = 'pointer';

            wrapper.appendChild(checkbox);
            wrapper.appendChild(label);

            if (index < 4) leftColumn.appendChild(wrapper);
            else rightColumn.appendChild(wrapper);
        });

        togglesContainer.appendChild(leftColumn);
        togglesContainer.appendChild(rightColumn);

        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.gap = '10px';
        buttonContainer.style.marginTop = '15px';

        const saveButton = createButton('Save', () => {
            const newDisabled = {};
            SECTIONS.forEach(section => {
                newDisabled[section.id] = document.getElementById(`section-${section.id}`).checked;
            });
            GM_setValue('backgroundColor', colorInput.value);
            GM_setValue('backgroundImage', bgImageInput.value);
            GM_setValue('profileImage', profileInput.value);
            GM_setValue('disabledSections', newDisabled);
            applySettings();
            expandContentHeight();
            modal.remove();
        });

        const resetButton = createButton('Reset to Defaults', () => {
            GM_setValue('backgroundColor', DEFAULTS.backgroundColor);
            GM_setValue('backgroundImage', DEFAULTS.backgroundImage);
            GM_setValue('profileImage', DEFAULTS.profileImage);
            GM_setValue('disabledSections', DEFAULTS.disabledSections);
            applySettings();
            expandContentHeight();
            modal.remove();
        });

        const closeButton = createButton('Close', () => modal.remove());

        form.append(colorLabel, colorInput,
                    bgImageLabel, bgImageInput,
                    profileLabel, profileInput,
                    sectionLabel);
        form.append(togglesContainer);
        buttonContainer.append(saveButton, resetButton, closeButton);
        modal.append(heading, form, buttonContainer);

        return modal;
    }

    // Initial setup
    applySettings();
    expandContentHeight();

    // Register menu command
    GM_registerMenuCommand('Open Better Daymap Settings', () => {
        document.body.appendChild(createSettingsPage());
    });

    // Helper functions
    function createLabel(text, forId) {
        const label = document.createElement('label');
        label.textContent = text;
        label.htmlFor = forId;
        label.style.fontWeight = 'bold';
        return label;
    }

    function createInput(type, id, value) {
        const input = document.createElement('input');
        input.type = type;
        input.id = id;
        input.value = value;
        input.style.padding = '5px';
        input.style.width = '100%';
        if (type === 'color') input.style.cursor = 'pointer';
        return input;
    }

    function createButton(text, onClick) {
        const button = document.createElement('button');
        button.textContent = text;
        button.onclick = onClick;
        button.style.cssText = `
            padding: 8px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            background: #007bff;
            color: white;
            transition: background 0.3s;
        `;
        button.addEventListener('mouseover', () => button.style.background = '#0056b3');
        button.addEventListener('mouseout', () => button.style.background = '#007bff');
        return button;
    }

    // Add custom CSS
    GM_addStyle(`
        /* Main layout improvements */
        .main-layout {
            padding: 20px;
            max-width: 14000px;
            margin: 0 auto;
        }

        .grid {
            gap: 0px;
        }

        .card {
            border-radius: 10px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            border: none;
            overflow: hidden;

        }

        /* Timetable styling */
        .tt {
            border-collapse: separate;
            border-spacing: 0;
            width: 100%;
        }

        .tt th {
            background: #1888C9;
            color: white;
            padding: 10px;
            text-align: center;
            font-weight: 500;
        }

        .tt td {
            padding: 0;
            border: 1px solid #e9ecef;
        }

        .ttCell {
            padding: 8px;
            height: 80px;
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            transition: all 0.2s ease;
        }

        .ttCell:hover {
            filter: brightness(95%);
            transform: translateY(-2px);
        }

        .ttSubject {
            font-weight: 600;
            font-size: 0.9rem;
            margin-bottom: 5px;
        }

        .ttTeacher, .ttRoom {
            font-size: 0.8rem;
            color: white;
        }

        .Period {
            background: #f8f9fa;
            font-weight: 500;
            padding: 8px;
            white-space: nowrap;
        }

        /* Task list improvements */
        .feed {
            width: 100%;
            border-collapse: collapse;
        }

        .feed tr {
            border-bottom: 1px solid #e9ecef;
        }

        .feed td {
            padding: 12px;
        }

        .feed .cap {
            width: 120px;
            font-weight: 500;
            color: #2c3e50;
            vertical-align: top;
        }

        .feed .itm {
            cursor: pointer;
            transition: background 0.2s ease;
        }

        .feed .itm:hover {
            background: #f8f9fa;
        }

        .Caption {
            font-size: 0.8rem;
            color: #6c757d;
        }

        /* Message list improvements */
        .msgList {
            padding: 0;
        }

        daymap-list-item {
            padding: 12px 15px;
            border-bottom: 1px solid #e9ecef;
            display: block;
            transition: background 0.2s ease;
        }

        daymap-list-item:hover {
            background: #f8f9fa;
        }

        /* Button improvements */
        .btn {
            border-radius: 6px;
            padding: 8px 16px;
            transition: all 0.2s ease;
        }

        .btn:hover {
            transform: translateY(-1px);
        }

        /* Responsive adjustments */
        @media (max-width: 768px) {
            .grid > div {
                width: 100% !important;
            }

            .ttCell {
                height: auto;
                min-height: 60px;
            }
        }
    `);

    // Wait for page to load
    window.addEventListener('load', function() {

        // Process timetable cells
        setTimeout(() => {
            const cells = document.querySelectorAll('.ttCell');
            cells.forEach(cell => {
                // Add hover effect
                cell.style.cursor = 'pointer';

                // Improve layout of cell content
                const subject = cell.querySelector('.ttSubject');
                if (subject) {
                    // Shorten long subject names
                    const text = subject.textContent.trim();
                    if (text.length > 25) {
                        subject.textContent = text.substring(0, 22) + '...';
                    }
                }
            });

            // Process task list
            const tasks = document.querySelectorAll('.feed .itm');
            tasks.forEach(task => {
                // Add hover effect
                task.style.transition = 'all 0.2s ease';

                // Color code based on status
                if (task.innerHTML.includes('Overdue')) {
                    task.style.borderLeft = '3px solid #e81123';
                } else if (task.innerHTML.includes('Uh did you submit on Turnitin or something?')) {
                    task.style.borderLeft = '3px solid #e81123';
                } else if (task.innerHTML.includes('Work has been received')) {
                    task.style.borderLeft = '3px solid #107c10';
                } else {
                    task.style.borderLeft = '3px solid #ffb900';
                }
            });
        });
    });
})();