File size: 9,139 Bytes
c001f24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
{% extends "base.html" %}

{% block title %}Browse Drive{% endblock %}

{% block styles %}
<style>
    .view-hidden { display: none !important; }
    .card-checkbox { 
        position: absolute; 
        top: 10px; 
        right: 10px; 
        z-index: 10; 
        width: 18px; 
        height: 18px; 
        cursor: pointer;
    }
    .list-view-row { cursor: pointer; }
    .list-view-row:hover { background-color: rgba(255,255,255,0.05); }
    .breadcrumb { margin-bottom: 0; }
</style>
{% endblock %}

{% block content %}
<div class="container-fluid mt-4" style="width: 90%; margin: auto;">
    
    <!-- Toolbar -->
    <div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-3">
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="/drive_manager">Drives</a></li>
                <li class="breadcrumb-item"><a href="/drive/browse/{{ source.id }}">{{ source.name }}</a></li>
                {% for crumb in breadcrumbs %}
                    <li class="breadcrumb-item active">{{ crumb.name }}</li>
                {% endfor %}
            </ol>
        </nav>

        <div class="d-flex gap-2">
            <div class="btn-group" role="group">
                <button type="button" class="btn btn-outline-secondary active" id="btn-view-grid" onclick="switchView('grid')" title="Grid View">
                    <i class="bi bi-grid-fill"></i>
                </button>
                <button type="button" class="btn btn-outline-secondary" id="btn-view-list" onclick="switchView('list')" title="List View">
                    <i class="bi bi-list-ul"></i>
                </button>
            </div>
        </div>
    </div>

    <!-- Bulk Actions Bar -->
    <div class="d-flex align-items-center mb-3 p-2 bg-dark border border-secondary rounded">
        <div class="form-check ms-2">
            <input class="form-check-input" type="checkbox" id="select-all">
            <label class="form-check-label user-select-none" for="select-all">Select All</label>
        </div>
        <div class="ms-auto" id="bulk-actions" style="visibility: hidden;">
            <span class="text-muted me-2 small"><span id="selected-count">0</span> selected</span>
            <!-- Add bulk actions here later if needed, e.g. Download -->
            <button class="btn btn-sm btn-outline-light" disabled>Bulk Actions (Coming Soon)</button>
        </div>
    </div>

    <!-- Grid View -->
    <div id="view-grid" class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4">
        {% for item in items %}
        <div class="col item-entry" data-id="{{ item.path }}">
            {% if item.type == 'folder' %}
                {% set link = '/drive/api/browse/' + item.path if is_api else '/drive/browse/' + source.id|string + '/' + item.path %}
                {% set icon = 'bi-folder-fill text-warning' %}
            {% else %}
                {% set link = '/drive/api/open/' + item.path if is_api else '/drive/file/' + source.id|string + '/' + item.path %}
                {% if item.type == 'pdf' %}
                    {% set icon = 'bi-file-earmark-pdf-fill text-danger' %}
                {% else %}
                    {% set icon = 'bi-file-earmark-image-fill text-info' %}
                {% endif %}
            {% endif %}

            <div class="card h-100 bg-dark text-white border-secondary position-relative">
                <input type="checkbox" class="form-check-input card-checkbox item-check" value="{{ item.path }}">
                <div class="card-body text-center" onclick="navigate('{{ link }}')" style="cursor: pointer;">
                    <i class="bi {{ icon }} fs-1"></i>
                    <h6 class="card-title mt-2 text-truncate" title="{{ item.name }}">{{ item.name }}</h6>
                </div>
            </div>
        </div>
        {% else %}
        <div class="col-12 text-center text-muted">
            <p>Empty folder or not synced yet.</p>
        </div>
        {% endfor %}
    </div>

    <!-- List View -->
    <div id="view-list" class="table-responsive view-hidden">
        <table class="table table-dark table-hover align-middle border-secondary">
            <thead>
                <tr>
                    <th style="width: 40px;"></th>
                    <th style="width: 50px;">Type</th>
                    <th>Name</th>
                    <th style="width: 100px;">Action</th>
                </tr>
            </thead>
            <tbody>
                {% for item in items %}
                {% if item.type == 'folder' %}
                    {% set link = '/drive/api/browse/' + item.path if is_api else '/drive/browse/' + source.id|string + '/' + item.path %}
                    {% set icon = 'bi-folder-fill text-warning' %}
                {% else %}
                    {% set link = '/drive/api/open/' + item.path if is_api else '/drive/file/' + source.id|string + '/' + item.path %}
                    {% if item.type == 'pdf' %}
                        {% set icon = 'bi-file-earmark-pdf-fill text-danger' %}
                    {% else %}
                        {% set icon = 'bi-file-earmark-image-fill text-info' %}
                    {% endif %}
                {% endif %}
                
                <tr class="item-entry">
                    <td><input type="checkbox" class="form-check-input item-check" value="{{ item.path }}"></td>
                    <td class="text-center"><i class="bi {{ icon }} fs-5"></i></td>
                    <td onclick="navigate('{{ link }}')" style="cursor: pointer;">
                        {{ item.name }}
                    </td>
                    <td>
                        <button class="btn btn-sm btn-outline-secondary" onclick="navigate('{{ link }}')">
                            Open
                        </button>
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
    </div>
</div>

<!-- Loader -->
<div id="loader-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.7); z-index:9999; align-items:center; justify-content:center; color:white; flex-direction:column;">
    <div class="spinner-border text-primary" role="status" style="width: 3rem; height: 3rem;"></div>
    <div class="mt-3 fs-5">Downloading & Opening...</div>
</div>

<script>
    // Navigation & Loader
    function showLoader() {
        document.getElementById('loader-overlay').style.display = 'flex';
    }

    function navigate(url) {
        showLoader();
        window.location.href = url;
    }

    // Fix Back Button Loader Issue
    window.addEventListener('pageshow', function(event) {
        document.getElementById('loader-overlay').style.display = 'none';
    });

    // View Switching
    function switchView(view) {
        const grid = document.getElementById('view-grid');
        const list = document.getElementById('view-list');
        const btnGrid = document.getElementById('btn-view-grid');
        const btnList = document.getElementById('btn-view-list');

        if (view === 'list') {
            grid.classList.add('view-hidden');
            list.classList.remove('view-hidden');
            btnList.classList.add('active');
            btnGrid.classList.remove('active');
            localStorage.setItem('driveViewMode', 'list');
        } else {
            list.classList.add('view-hidden');
            grid.classList.remove('view-hidden');
            btnGrid.classList.add('active');
            btnList.classList.remove('active');
            localStorage.setItem('driveViewMode', 'grid');
        }
    }

    // Checkbox Logic
    const selectAll = document.getElementById('select-all');
    const checkboxes = document.querySelectorAll('.item-check');
    const bulkActions = document.getElementById('bulk-actions');
    const selectedCount = document.getElementById('selected-count');

    function updateSelection() {
        const checked = document.querySelectorAll('.item-check:checked');
        const count = checked.length;
        selectedCount.textContent = count;
        bulkActions.style.visibility = count > 0 ? 'visible' : 'hidden';
        
        // Sync select all checkbox state
        if (count === 0) selectAll.checked = false;
        else if (count === checkboxes.length) selectAll.checked = true;
        else selectAll.indeterminate = true;
    }

    selectAll.addEventListener('change', (e) => {
        const isChecked = e.target.checked;
        checkboxes.forEach(cb => {
            // Only toggle visible items if we had filtering, but here we toggle all
            cb.checked = isChecked;
        });
        updateSelection();
    });

    checkboxes.forEach(cb => {
        cb.addEventListener('change', updateSelection);
        cb.addEventListener('click', (e) => e.stopPropagation()); // Prevent card click
    });

    // Init
    document.addEventListener('DOMContentLoaded', () => {
        const savedView = localStorage.getItem('driveViewMode') || 'grid';
        switchView(savedView);
    });
</script>
{% endblock %}