@necrolab/dashboard 0.5.27 → 0.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend/api.js +7 -5
- package/backend/batching.js +59 -2
- package/backend/index.js +1 -1
- package/index.html +10 -23
- package/package.json +1 -1
- package/src/assets/css/base/scroll.scss +1 -1
- package/src/assets/css/main.scss +14 -14
- package/src/components/Console/ConsoleToolbar.vue +8 -8
- package/src/components/Editors/Account/Account.vue +9 -5
- package/src/components/Editors/Account/AccountView.vue +37 -18
- package/src/components/Editors/Account/CreateAccount.vue +38 -4
- package/src/components/Editors/Profile/CreateProfile.vue +29 -4
- package/src/components/Editors/Profile/Profile.vue +11 -6
- package/src/components/Editors/Profile/ProfileCountryChooser.vue +2 -2
- package/src/components/Editors/Profile/ProfileView.vue +37 -18
- package/src/components/Tasks/CreateTaskAXS.vue +16 -2
- package/src/components/Tasks/CreateTaskTM.vue +28 -5
- package/src/components/Tasks/QuickSettings.vue +77 -10
- package/src/components/Tasks/Task.vue +24 -8
- package/src/components/Tasks/TaskView.vue +144 -58
- package/src/components/Tasks/ViewTask.vue +17 -3
- package/src/components/ui/Modal.vue +1 -1
- package/src/components/ui/ReadonlyFieldsSection.vue +3 -3
- package/src/components/ui/StatusBadge.vue +1 -1
- package/src/components/ui/TaskToggle.vue +2 -3
- package/src/components/ui/controls/CountryChooser.vue +2 -2
- package/src/components/ui/controls/atomic/Dropdown.vue +2 -2
- package/src/components/ui/controls/atomic/MultiDropdown.vue +1 -1
- package/src/composables/useDynamicTableHeight.js +4 -4
- package/src/composables/useRowSelection.js +0 -1
- package/src/composables/useZoomPrevention.js +16 -55
- package/src/stores/connection.js +453 -68
- package/src/stores/sampleData.js +34 -24
- package/src/stores/ui.js +89 -100
- package/src/views/Accounts.vue +2 -5
- package/src/views/Console.vue +13 -14
- package/src/views/Profiles.vue +2 -5
- package/vite.config.js +4 -2
package/src/stores/sampleData.js
CHANGED
|
@@ -27,7 +27,7 @@ export default {
|
|
|
27
27
|
proxy: "http://events1597:yEXBe4Hs@23.26.22.61:61234",
|
|
28
28
|
eventId: "grantelam@hotmail.com",
|
|
29
29
|
reservedTicketsList: "• 2x 301/E ($86.47) \n• 2x 306/U ($86.47) \n$345.88",
|
|
30
|
-
expirationTime:
|
|
30
|
+
expirationTime: new Date(Date.now() + 8 * 60 * 1000).toISOString(),
|
|
31
31
|
doNotPay: false,
|
|
32
32
|
inQueue: true,
|
|
33
33
|
agedAccount: true,
|
|
@@ -63,7 +63,7 @@ export default {
|
|
|
63
63
|
proxy: "http://events1338:xN4PBVze@23.26.21.58:61234",
|
|
64
64
|
eventId: "01005D85964A1747",
|
|
65
65
|
reservedTicketsList: "• 2x 301/E ($86.47) \n• 2x 306/U ($86.47) \n$345.88",
|
|
66
|
-
expirationTime:
|
|
66
|
+
expirationTime: new Date(Date.now() + 5 * 60 * 1000).toISOString(),
|
|
67
67
|
doNotPay: false,
|
|
68
68
|
agedAccount: false,
|
|
69
69
|
presaleCode: "",
|
|
@@ -902,7 +902,8 @@ export default {
|
|
|
902
902
|
expYear: "28",
|
|
903
903
|
country: "US",
|
|
904
904
|
state: "NY",
|
|
905
|
-
tags: ["admin", "amex"]
|
|
905
|
+
tags: ["admin", "amex"],
|
|
906
|
+
enabled: true
|
|
906
907
|
},
|
|
907
908
|
{
|
|
908
909
|
id: 2,
|
|
@@ -910,7 +911,8 @@ export default {
|
|
|
910
911
|
cardNumber: "3847463847454545",
|
|
911
912
|
expMonth: "12",
|
|
912
913
|
expYear: "28",
|
|
913
|
-
tags: ["admin", "amex"]
|
|
914
|
+
tags: ["admin", "amex"],
|
|
915
|
+
enabled: true
|
|
914
916
|
},
|
|
915
917
|
{
|
|
916
918
|
id: 3,
|
|
@@ -922,23 +924,25 @@ export default {
|
|
|
922
924
|
enabled: true
|
|
923
925
|
},
|
|
924
926
|
{
|
|
925
|
-
id:
|
|
927
|
+
id: 4,
|
|
926
928
|
profileName: "Harry Potter",
|
|
927
929
|
cardNumber: "4847463847454545",
|
|
928
930
|
expMonth: "12",
|
|
929
931
|
expYear: "28",
|
|
930
|
-
tags: ["admin", "amex"]
|
|
932
|
+
tags: ["admin", "amex"],
|
|
933
|
+
enabled: true
|
|
931
934
|
},
|
|
932
935
|
{
|
|
933
|
-
id:
|
|
936
|
+
id: 5,
|
|
934
937
|
profileName: "Draco Malfoy",
|
|
935
938
|
cardNumber: "3847463847454545",
|
|
936
939
|
expMonth: "12",
|
|
937
940
|
expYear: "28",
|
|
938
|
-
tags: ["admin", "amex"]
|
|
941
|
+
tags: ["admin", "amex"],
|
|
942
|
+
enabled: true
|
|
939
943
|
},
|
|
940
944
|
{
|
|
941
|
-
id:
|
|
945
|
+
id: 6,
|
|
942
946
|
profileName: "Tom Smith",
|
|
943
947
|
cardNumber: "5847463847454545",
|
|
944
948
|
expMonth: "12",
|
|
@@ -947,23 +951,25 @@ export default {
|
|
|
947
951
|
enabled: true
|
|
948
952
|
},
|
|
949
953
|
{
|
|
950
|
-
id:
|
|
954
|
+
id: 7,
|
|
951
955
|
profileName: "Harry Potter",
|
|
952
956
|
cardNumber: "4847463847454545",
|
|
953
957
|
expMonth: "12",
|
|
954
958
|
expYear: "28",
|
|
955
|
-
tags: ["admin", "amex"]
|
|
959
|
+
tags: ["admin", "amex"],
|
|
960
|
+
enabled: true
|
|
956
961
|
},
|
|
957
962
|
{
|
|
958
|
-
id:
|
|
963
|
+
id: 8,
|
|
959
964
|
profileName: "Draco Malfoy",
|
|
960
965
|
cardNumber: "3847463847454545",
|
|
961
966
|
expMonth: "12",
|
|
962
967
|
expYear: "28",
|
|
963
|
-
tags: ["admin", "amex"]
|
|
968
|
+
tags: ["admin", "amex"],
|
|
969
|
+
enabled: true
|
|
964
970
|
},
|
|
965
971
|
{
|
|
966
|
-
id:
|
|
972
|
+
id: 9,
|
|
967
973
|
profileName: "Tom Smith",
|
|
968
974
|
cardNumber: "5847463847454545",
|
|
969
975
|
expMonth: "12",
|
|
@@ -972,23 +978,25 @@ export default {
|
|
|
972
978
|
enabled: true
|
|
973
979
|
},
|
|
974
980
|
{
|
|
975
|
-
id:
|
|
981
|
+
id: 10,
|
|
976
982
|
profileName: "Harry Potter",
|
|
977
983
|
cardNumber: "4847463847454545",
|
|
978
984
|
expMonth: "12",
|
|
979
985
|
expYear: "28",
|
|
980
|
-
tags: ["admin", "amex"]
|
|
986
|
+
tags: ["admin", "amex"],
|
|
987
|
+
enabled: true
|
|
981
988
|
},
|
|
982
989
|
{
|
|
983
|
-
id:
|
|
990
|
+
id: 11,
|
|
984
991
|
profileName: "Draco Malfoy",
|
|
985
992
|
cardNumber: "3847463847454545",
|
|
986
993
|
expMonth: "12",
|
|
987
994
|
expYear: "28",
|
|
988
|
-
tags: ["admin", "amex"]
|
|
995
|
+
tags: ["admin", "amex"],
|
|
996
|
+
enabled: true
|
|
989
997
|
},
|
|
990
998
|
{
|
|
991
|
-
id:
|
|
999
|
+
id: 12,
|
|
992
1000
|
profileName: "Tom Smith",
|
|
993
1001
|
cardNumber: "5847463847454545",
|
|
994
1002
|
expMonth: "12",
|
|
@@ -997,23 +1005,25 @@ export default {
|
|
|
997
1005
|
enabled: true
|
|
998
1006
|
},
|
|
999
1007
|
{
|
|
1000
|
-
id:
|
|
1008
|
+
id: 13,
|
|
1001
1009
|
profileName: "Harry Potter",
|
|
1002
1010
|
cardNumber: "4847463847454545",
|
|
1003
1011
|
expMonth: "12",
|
|
1004
1012
|
expYear: "28",
|
|
1005
|
-
tags: ["admin", "amex"]
|
|
1013
|
+
tags: ["admin", "amex"],
|
|
1014
|
+
enabled: true
|
|
1006
1015
|
},
|
|
1007
1016
|
{
|
|
1008
|
-
id:
|
|
1017
|
+
id: 14,
|
|
1009
1018
|
profileName: "Draco Malfoy",
|
|
1010
1019
|
cardNumber: "3847463847454545",
|
|
1011
1020
|
expMonth: "12",
|
|
1012
1021
|
expYear: "28",
|
|
1013
|
-
tags: ["admin", "amex"]
|
|
1022
|
+
tags: ["admin", "amex"],
|
|
1023
|
+
enabled: true
|
|
1014
1024
|
},
|
|
1015
1025
|
{
|
|
1016
|
-
id:
|
|
1026
|
+
id: 15,
|
|
1017
1027
|
profileName: "Tom Smith",
|
|
1018
1028
|
cardNumber: "5847463847454545",
|
|
1019
1029
|
expMonth: "12",
|
package/src/stores/ui.js
CHANGED
|
@@ -3,7 +3,6 @@ import { defineStore } from "pinia";
|
|
|
3
3
|
import { ConnectionHandler } from "@/stores/connection.js";
|
|
4
4
|
import { toast } from "vue3-toastify";
|
|
5
5
|
import { createLogger } from "@/stores/logger";
|
|
6
|
-
import { timeDifference } from "@/libs/utils/time";
|
|
7
6
|
import { betterSort, sortTaskIds } from "@/libs/utils/array";
|
|
8
7
|
|
|
9
8
|
const TOAST_CONFIG = {
|
|
@@ -109,94 +108,71 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
109
108
|
});
|
|
110
109
|
const currentDropdown = ref("");
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let
|
|
115
|
-
let lastSyncCheck = 0;
|
|
116
|
-
let rafId = null;
|
|
111
|
+
const taskTimeTick = ref(Date.now());
|
|
112
|
+
let tickInterval = null;
|
|
113
|
+
let syncCounterMs = 0;
|
|
117
114
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
lastTimeUpdate = timestamp;
|
|
122
|
-
const now = Date.now();
|
|
115
|
+
const syncTaskIdOrder = () => {
|
|
116
|
+
const allIds = new Set(Object.keys(tasks.value));
|
|
117
|
+
const orderIds = new Set(taskIdOrder.value);
|
|
123
118
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
119
|
+
const missingIds = [...allIds].filter((id) => !orderIds.has(id));
|
|
120
|
+
const extraIds = [...orderIds].filter((id) => !allIds.has(id));
|
|
121
|
+
|
|
122
|
+
if (missingIds.length === 0 && extraIds.length === 0) return;
|
|
123
|
+
|
|
124
|
+
taskIdOrder.value = taskIdOrder.value.filter((id) => allIds.has(id));
|
|
125
|
+
if (missingIds.length === 0) return;
|
|
126
|
+
|
|
127
|
+
missingIds.sort(sortTaskIds);
|
|
128
|
+
for (const id of missingIds) {
|
|
129
|
+
let left = 0;
|
|
130
|
+
let right = taskIdOrder.value.length;
|
|
131
|
+
while (left < right) {
|
|
132
|
+
const mid = Math.floor((left + right) / 2);
|
|
133
|
+
if (sortTaskIds(id, taskIdOrder.value[mid]) < 0) right = mid;
|
|
134
|
+
else left = mid + 1;
|
|
133
135
|
}
|
|
136
|
+
taskIdOrder.value.splice(left, 0, id);
|
|
134
137
|
}
|
|
138
|
+
};
|
|
135
139
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const missingIds = [...allIds].filter((id) => !orderIds.has(id));
|
|
143
|
-
const extraIds = [...orderIds].filter((id) => !allIds.has(id));
|
|
144
|
-
|
|
145
|
-
if (missingIds.length > 0 || extraIds.length > 0) {
|
|
146
|
-
taskIdOrder.value = taskIdOrder.value.filter((id) => allIds.has(id));
|
|
147
|
-
|
|
148
|
-
if (missingIds.length > 0) {
|
|
149
|
-
missingIds.sort(sortTaskIds);
|
|
150
|
-
// Optimized: Binary search for insertion point
|
|
151
|
-
for (const id of missingIds) {
|
|
152
|
-
let left = 0;
|
|
153
|
-
let right = taskIdOrder.value.length;
|
|
154
|
-
while (left < right) {
|
|
155
|
-
const mid = Math.floor((left + right) / 2);
|
|
156
|
-
if (sortTaskIds(id, taskIdOrder.value[mid]) < 0) {
|
|
157
|
-
right = mid;
|
|
158
|
-
} else {
|
|
159
|
-
left = mid + 1;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
taskIdOrder.value.splice(left, 0, id);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
140
|
+
const tickTaskTimers = () => {
|
|
141
|
+
taskTimeTick.value = Date.now();
|
|
142
|
+
syncCounterMs += 1000;
|
|
143
|
+
if (syncCounterMs >= 10000) {
|
|
144
|
+
syncCounterMs = 0;
|
|
145
|
+
syncTaskIdOrder();
|
|
166
146
|
}
|
|
147
|
+
};
|
|
167
148
|
|
|
168
|
-
|
|
149
|
+
const startTaskTimerTicking = () => {
|
|
150
|
+
if (tickInterval) return;
|
|
151
|
+
tickInterval = setInterval(tickTaskTimers, 1000);
|
|
169
152
|
};
|
|
170
153
|
|
|
171
|
-
|
|
154
|
+
const stopTaskTimerTicking = () => {
|
|
155
|
+
if (!tickInterval) return;
|
|
156
|
+
clearInterval(tickInterval);
|
|
157
|
+
tickInterval = null;
|
|
158
|
+
};
|
|
172
159
|
|
|
173
|
-
|
|
174
|
-
|
|
160
|
+
startTaskTimerTicking();
|
|
161
|
+
|
|
162
|
+
document.addEventListener("visibilitychange", () => {
|
|
175
163
|
if (document.hidden) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
rafId = null;
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
if (!rafId) {
|
|
182
|
-
lastTimeUpdate = 0;
|
|
183
|
-
lastSyncCheck = 0;
|
|
184
|
-
rafId = requestAnimationFrame(updateTaskTimes);
|
|
185
|
-
}
|
|
164
|
+
stopTaskTimerTicking();
|
|
165
|
+
return;
|
|
186
166
|
}
|
|
167
|
+
|
|
168
|
+
syncCounterMs = 0;
|
|
169
|
+
taskTimeTick.value = Date.now();
|
|
170
|
+
syncTaskIdOrder();
|
|
171
|
+
startTaskTimerTicking();
|
|
187
172
|
});
|
|
188
173
|
|
|
189
174
|
connection.init("/api/updates?type=tasks");
|
|
190
175
|
|
|
191
|
-
const pd = (e) => {
|
|
192
|
-
if (
|
|
193
|
-
!e.target.closest(".scrollable") &&
|
|
194
|
-
!e.target.closest(".dropdown-menu") &&
|
|
195
|
-
!e.target.closest(".option-list")
|
|
196
|
-
) {
|
|
197
|
-
e.preventDefault();
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
176
|
const preventScroll = () => {
|
|
201
177
|
const scrollY = window.scrollY;
|
|
202
178
|
document.body.style.position = "fixed";
|
|
@@ -230,8 +206,6 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
230
206
|
input.style.touchAction = "pan-x pan-y";
|
|
231
207
|
});
|
|
232
208
|
|
|
233
|
-
// Prevent touch moves
|
|
234
|
-
document.addEventListener("touchmove", pd, { passive: false });
|
|
235
209
|
};
|
|
236
210
|
|
|
237
211
|
const enableScroll = () => {
|
|
@@ -269,34 +243,45 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
269
243
|
// Restore scroll position
|
|
270
244
|
window.scrollTo(0, parseInt(scrollY || "0") * -1);
|
|
271
245
|
|
|
272
|
-
// Remove event listener
|
|
273
|
-
document.removeEventListener("touchmove", pd);
|
|
274
246
|
};
|
|
275
247
|
|
|
276
248
|
const refreshQueueStats = () => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
249
|
+
const siteId = currentCountry.value.siteId;
|
|
250
|
+
const eventId = currentEvent.value;
|
|
251
|
+
const sleepingStatuses = new Set([
|
|
252
|
+
"sleeping in queue",
|
|
253
|
+
"waiting for drop",
|
|
254
|
+
"waiting for carting",
|
|
255
|
+
"waiting for queue"
|
|
256
|
+
]);
|
|
257
|
+
|
|
258
|
+
let total = 0;
|
|
259
|
+
let queued = 0;
|
|
260
|
+
let sleeping = 0;
|
|
261
|
+
const positions = [];
|
|
262
|
+
|
|
263
|
+
for (const task of Object.values(tasks.value)) {
|
|
264
|
+
if (!task || task.siteId !== siteId) continue;
|
|
265
|
+
if (eventId && task.eventId !== eventId) continue;
|
|
266
|
+
|
|
267
|
+
total++;
|
|
268
|
+
if (task.inQueue) queued++;
|
|
269
|
+
|
|
270
|
+
const status = typeof task.status === "string" ? task.status.toLowerCase() : "";
|
|
271
|
+
if (sleepingStatuses.has(status)) sleeping++;
|
|
272
|
+
|
|
273
|
+
const queuePosition = Number(task.queuePosition);
|
|
274
|
+
if (Number.isFinite(queuePosition) && queuePosition > 0) {
|
|
275
|
+
positions.push(queuePosition);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
positions.sort((a, b) => a - b);
|
|
280
|
+
queueStats.value.total = total;
|
|
281
|
+
queueStats.value.queued = queued;
|
|
282
|
+
queueStats.value.sleeping = sleeping;
|
|
283
|
+
queueStats.value.nextQueuePasses = positions;
|
|
284
|
+
queueStats.value.show = queued > 0 || sleeping > 0 || positions.length > 0;
|
|
300
285
|
};
|
|
301
286
|
|
|
302
287
|
const toggleModal = (name, clearValue = false) => {
|
|
@@ -466,6 +451,7 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
466
451
|
|
|
467
452
|
// refresh
|
|
468
453
|
tasks,
|
|
454
|
+
taskTimeTick,
|
|
469
455
|
|
|
470
456
|
// top main checkbox
|
|
471
457
|
mainCheckbox,
|
|
@@ -580,6 +566,9 @@ export const useUIStore = defineStore("ui", () => {
|
|
|
580
566
|
} else accounts.value.push({ ...acc, id: Math.random() });
|
|
581
567
|
},
|
|
582
568
|
setAccounts: (accs) => accounts.value.push(...accs),
|
|
569
|
+
setAccountsForModule: (module, accs) => {
|
|
570
|
+
accounts.value = [...accounts.value.filter((account) => account.module !== module), ...accs];
|
|
571
|
+
},
|
|
583
572
|
profiles,
|
|
584
573
|
addProfile: (profile) => {
|
|
585
574
|
if (!DEBUG) return connection.sendSaveProfile(profile);
|
package/src/views/Accounts.vue
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<div class="page-header-card">
|
|
5
5
|
<MailIcon />
|
|
6
6
|
<h4>Accounts</h4>
|
|
7
|
+
<span class="pl-1.5 text-sm font-medium text-light-400">{{ ui.accounts.length }}</span>
|
|
7
8
|
</div>
|
|
8
9
|
<ul class="mobile-icons">
|
|
9
10
|
<li>
|
|
@@ -84,7 +85,7 @@
|
|
|
84
85
|
</div>
|
|
85
86
|
|
|
86
87
|
<!-- Tasks (Table) -->
|
|
87
|
-
<AccountView :accounts="
|
|
88
|
+
<AccountView :accounts="ui.search.accounts.results" :privacy="privacy" />
|
|
88
89
|
|
|
89
90
|
<!-- Modal -->
|
|
90
91
|
<transition-group name="fade">
|
|
@@ -130,10 +131,6 @@ const filterAccounts = () => {
|
|
|
130
131
|
|
|
131
132
|
ui.search.accounts.results = filterAccounts();
|
|
132
133
|
|
|
133
|
-
const processedTasks = computed(() => {
|
|
134
|
-
return ui.search.accounts.results.map((e) => ({ ...e, privacy: privacy.value }));
|
|
135
|
-
});
|
|
136
|
-
|
|
137
134
|
watch(
|
|
138
135
|
() =>
|
|
139
136
|
ui.search.accounts.query +
|
package/src/views/Console.vue
CHANGED
|
@@ -22,13 +22,10 @@
|
|
|
22
22
|
@autoscroll-toggle="onAutoscrollToggle" />
|
|
23
23
|
</div>
|
|
24
24
|
|
|
25
|
-
<
|
|
26
|
-
:weight="0.2"
|
|
25
|
+
<div
|
|
27
26
|
class="console-main"
|
|
28
27
|
:style="consoleMainStyle"
|
|
29
28
|
ref="$autoscroll"
|
|
30
|
-
@wheel.stop
|
|
31
|
-
@touchmove.stop
|
|
32
29
|
@scroll="handleScroll">
|
|
33
30
|
<div
|
|
34
31
|
v-if="displayedLogs.length === 0"
|
|
@@ -47,7 +44,7 @@
|
|
|
47
44
|
v-for="(line, index) in displayedLogs"
|
|
48
45
|
v-bind:key="`log-${index}`"
|
|
49
46
|
:style="{ '--index': index }"><code class="md:text-sm lg:text-base mobile-portrait:text-xs+ mobile-portrait:leading-tight" v-html="line"></code></pre>
|
|
50
|
-
</
|
|
47
|
+
</div>
|
|
51
48
|
</div>
|
|
52
49
|
</div>
|
|
53
50
|
</template>
|
|
@@ -105,7 +102,6 @@
|
|
|
105
102
|
}
|
|
106
103
|
</style>
|
|
107
104
|
<script setup>
|
|
108
|
-
import { Smoothie } from "vue-smoothie";
|
|
109
105
|
import { DEBUG } from "@/utils/debug";
|
|
110
106
|
|
|
111
107
|
import Filter from "@/libs/ansii.js";
|
|
@@ -168,6 +164,11 @@ const SCROLL_THRESHOLD = 100;
|
|
|
168
164
|
const SCROLL_AMOUNT = 100;
|
|
169
165
|
const MIN_CONSOLE_HEIGHT = 192;
|
|
170
166
|
|
|
167
|
+
const getConsoleScrollElement = () => {
|
|
168
|
+
if (!$autoscroll.value) return null;
|
|
169
|
+
return $autoscroll.value?.el || $autoscroll.value;
|
|
170
|
+
};
|
|
171
|
+
|
|
171
172
|
const getTableHeightCap = (viewportHeight) => {
|
|
172
173
|
const isPWA = window.matchMedia("(display-mode: standalone)").matches;
|
|
173
174
|
const isMobile = window.innerWidth <= 768;
|
|
@@ -197,7 +198,7 @@ const consoleMainStyle = computed(() => {
|
|
|
197
198
|
});
|
|
198
199
|
|
|
199
200
|
const updateConsoleHeight = () => {
|
|
200
|
-
const element =
|
|
201
|
+
const element = getConsoleScrollElement();
|
|
201
202
|
if (!element) return;
|
|
202
203
|
|
|
203
204
|
const viewportHeight = window.visualViewport?.height || window.innerHeight;
|
|
@@ -232,13 +233,12 @@ const handleScroll = (event) => {
|
|
|
232
233
|
|
|
233
234
|
const performScroll = (direction, smooth = true) => {
|
|
234
235
|
try {
|
|
235
|
-
|
|
236
|
+
const element = getConsoleScrollElement();
|
|
237
|
+
if (!element) {
|
|
236
238
|
if (DEBUG) return false;
|
|
237
239
|
return false;
|
|
238
240
|
}
|
|
239
241
|
|
|
240
|
-
const element = $autoscroll.value.el;
|
|
241
|
-
|
|
242
242
|
if (direction === "up") {
|
|
243
243
|
if (smooth && element.scrollTo) {
|
|
244
244
|
element.scrollTo({ top: 0, behavior: "smooth" });
|
|
@@ -273,7 +273,7 @@ const startScrolling = (direction) => {
|
|
|
273
273
|
const continuousScroll = () => {
|
|
274
274
|
if (!isScrolling.value) return;
|
|
275
275
|
|
|
276
|
-
const element =
|
|
276
|
+
const element = getConsoleScrollElement();
|
|
277
277
|
if (!element) return;
|
|
278
278
|
|
|
279
279
|
if (direction === "up") {
|
|
@@ -297,9 +297,8 @@ const stopScrolling = () => {
|
|
|
297
297
|
};
|
|
298
298
|
|
|
299
299
|
const autoScrollToBottom = () => {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const element = $autoscroll.value.el;
|
|
300
|
+
const element = getConsoleScrollElement();
|
|
301
|
+
if (!element || !autoscrollToggled.value) return;
|
|
303
302
|
const targetScrollTop = element.scrollHeight - element.clientHeight;
|
|
304
303
|
const currentDistanceFromBottom = element.scrollHeight - element.scrollTop - element.clientHeight;
|
|
305
304
|
|
package/src/views/Profiles.vue
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
<div class="page-header-card">
|
|
5
5
|
<GroupIcon />
|
|
6
6
|
<h4>Profiles</h4>
|
|
7
|
+
<span class="pl-1.5 text-sm font-medium text-light-400">{{ ui.profiles.length }}</span>
|
|
7
8
|
</div>
|
|
8
9
|
<ul class="mobile-icons">
|
|
9
10
|
<li>
|
|
@@ -109,7 +110,7 @@
|
|
|
109
110
|
</div>
|
|
110
111
|
|
|
111
112
|
<!-- Tasks (Table) -->
|
|
112
|
-
<ProfileView :profiles="
|
|
113
|
+
<ProfileView :profiles="ui.search.profiles.results" :privacy="privacy" />
|
|
113
114
|
|
|
114
115
|
<!-- Modal -->
|
|
115
116
|
<transition-group name="fade">
|
|
@@ -138,10 +139,6 @@ const filterFieldMap = { Name: "profileName", Card: "cardNumber" };
|
|
|
138
139
|
const allTags = ref([]);
|
|
139
140
|
const privacy = ref(true);
|
|
140
141
|
|
|
141
|
-
const processedTasks = computed(() => {
|
|
142
|
-
return ui.search.profiles.results.map((e) => ({ ...e, privacy: privacy.value }));
|
|
143
|
-
});
|
|
144
|
-
|
|
145
142
|
watch(
|
|
146
143
|
() =>
|
|
147
144
|
ui.search.profiles.query +
|
package/vite.config.js
CHANGED
|
@@ -49,7 +49,8 @@ export default defineConfig({
|
|
|
49
49
|
preprocessorOptions: {
|
|
50
50
|
scss: {
|
|
51
51
|
api: "modern-compiler",
|
|
52
|
-
silenceDeprecations: ["legacy-js-api"]
|
|
52
|
+
silenceDeprecations: ["legacy-js-api"],
|
|
53
|
+
loadPaths: [fileURLToPath(new URL("./src/assets/css", import.meta.url))]
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
56
|
devSourcemap: true
|
|
@@ -66,7 +67,8 @@ export default defineConfig({
|
|
|
66
67
|
// Handle iOS connection resets gracefully
|
|
67
68
|
watch: {
|
|
68
69
|
usePolling: false,
|
|
69
|
-
interval: 1000
|
|
70
|
+
interval: 1000,
|
|
71
|
+
ignored: ["**/dist/**"]
|
|
70
72
|
},
|
|
71
73
|
proxy: {
|
|
72
74
|
"/api": {
|