[call-me] - feat: use RINGING_TIMEOUT env var for call timeout, dynamic progress bar, and looping ring sound
This commit is contained in:
+5
-1
@@ -76,4 +76,8 @@ PUSH_VAPID_EMAIL='mailto:admin@example.com'
|
|||||||
SENTRY_ENABLED=false # true or false
|
SENTRY_ENABLED=false # true or false
|
||||||
SENTRY_LOG_LEVELS=error # Log levels to capture in Sentry (e.g., error,warn)
|
SENTRY_LOG_LEVELS=error # Log levels to capture in Sentry (e.g., error,warn)
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
SENTRY_TRACES_SAMPLE_RATE=0.5 # Adjust the sample rate for performance monitoring (0.0 to 1.0)
|
SENTRY_TRACES_SAMPLE_RATE=0.5 # Adjust the sample rate for performance monitoring (0.0 to 1.0)
|
||||||
|
|
||||||
|
# Time in seconds before a call is considered unanswered (default 30 seconds)
|
||||||
|
|
||||||
|
RINGING_TIMEOUT=30
|
||||||
@@ -92,6 +92,7 @@ const config = {
|
|||||||
pushVapidPrivateKey: process.env.PUSH_VAPID_PRIVATE_KEY || '',
|
pushVapidPrivateKey: process.env.PUSH_VAPID_PRIVATE_KEY || '',
|
||||||
pushVapidEmail: process.env.PUSH_VAPID_EMAIL || 'mailto:admin@example.com',
|
pushVapidEmail: process.env.PUSH_VAPID_EMAIL || 'mailto:admin@example.com',
|
||||||
randomImageUrl: process.env.RANDOM_IMAGE_URL || '',
|
randomImageUrl: process.env.RANDOM_IMAGE_URL || '',
|
||||||
|
ringTimeout: parseInt(process.env.RINGING_TIMEOUT, 10) || 30,
|
||||||
apiBasePath: '/api/v1',
|
apiBasePath: '/api/v1',
|
||||||
swaggerDocument: yaml.load(fs.readFileSync(path.join(__dirname, '/api/swagger.yaml'), 'utf8')),
|
swaggerDocument: yaml.load(fs.readFileSync(path.join(__dirname, '/api/swagger.yaml'), 'utf8')),
|
||||||
};
|
};
|
||||||
@@ -529,6 +530,7 @@ function handleConnection(socket) {
|
|||||||
message: 'Hello Client!',
|
message: 'Hello Client!',
|
||||||
iceServers: config.iceServers,
|
iceServers: config.iceServers,
|
||||||
pushEnabled: config.pushEnabled,
|
pushEnabled: config.pushEnabled,
|
||||||
|
ringTimeout: config.ringTimeout,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+21
-66
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "call-me",
|
"name": "call-me",
|
||||||
"version": "1.3.44",
|
"version": "1.3.45",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "call-me",
|
"name": "call-me",
|
||||||
"version": "1.3.44",
|
"version": "1.3.45",
|
||||||
"license": "AGPLv3",
|
"license": "AGPLv3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ngrok/ngrok": "1.7.0",
|
"@ngrok/ngrok": "1.7.0",
|
||||||
"@sentry/node": "^10.51.0",
|
"@sentry/node": "^10.52.0",
|
||||||
"axios": "^1.16.0",
|
"axios": "^1.16.0",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
@@ -522,23 +522,6 @@
|
|||||||
"@opentelemetry/api": ">=1.0.0 <1.10.0"
|
"@opentelemetry/api": ">=1.0.0 <1.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@opentelemetry/instrumentation-ioredis": {
|
|
||||||
"version": "0.62.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.62.0.tgz",
|
|
||||||
"integrity": "sha512-ZYt//zcPve8qklaZX+5Z4MkU7UpEkFRrxsf2cnaKYBitqDnsCN69CPAuuMOX6NYdW2rG9sFy7V/QWtBlP5XiNQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@opentelemetry/instrumentation": "^0.214.0",
|
|
||||||
"@opentelemetry/redis-common": "^0.38.2",
|
|
||||||
"@opentelemetry/semantic-conventions": "^1.33.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^18.19.0 || >=20.6.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@opentelemetry/api": "^1.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@opentelemetry/instrumentation-kafkajs": {
|
"node_modules/@opentelemetry/instrumentation-kafkajs": {
|
||||||
"version": "0.23.0",
|
"version": "0.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.23.0.tgz",
|
||||||
@@ -690,23 +673,6 @@
|
|||||||
"@opentelemetry/api": "^1.3.0"
|
"@opentelemetry/api": "^1.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@opentelemetry/instrumentation-redis": {
|
|
||||||
"version": "0.62.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.62.0.tgz",
|
|
||||||
"integrity": "sha512-y3pPpot7WzR/8JtHcYlTYsyY8g+pbFhAqbwAuG5bLPnR6v6pt1rQc0DpH0OlGP/9CZbWBP+Zhwp9yFoygf/ZXQ==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@opentelemetry/instrumentation": "^0.214.0",
|
|
||||||
"@opentelemetry/redis-common": "^0.38.2",
|
|
||||||
"@opentelemetry/semantic-conventions": "^1.27.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^18.19.0 || >=20.6.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@opentelemetry/api": "^1.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@opentelemetry/instrumentation-tedious": {
|
"node_modules/@opentelemetry/instrumentation-tedious": {
|
||||||
"version": "0.33.0",
|
"version": "0.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.33.0.tgz",
|
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.33.0.tgz",
|
||||||
@@ -724,15 +690,6 @@
|
|||||||
"@opentelemetry/api": "^1.3.0"
|
"@opentelemetry/api": "^1.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@opentelemetry/redis-common": {
|
|
||||||
"version": "0.38.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.3.tgz",
|
|
||||||
"integrity": "sha512-VCghU1JYs/4gP6Gqf/xro9MEsZ7LrMv2uONVsaESKL38ZOB9BqnI98FfS23wjMnHlpuE+TTaWSoAVNpTwYXzjw==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"engines": {
|
|
||||||
"node": "^18.19.0 || >=20.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@opentelemetry/resources": {
|
"node_modules/@opentelemetry/resources": {
|
||||||
"version": "2.7.1",
|
"version": "2.7.1",
|
||||||
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz",
|
"resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz",
|
||||||
@@ -844,18 +801,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/core": {
|
"node_modules/@sentry/core": {
|
||||||
"version": "10.51.0",
|
"version": "10.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.52.0.tgz",
|
||||||
"integrity": "sha512-Y45V/YXvVLEXmOdkbD1oG1gkRWFi9guCEGg3PlIlIpRjAbZUrvLGgjRJIc1E7XpSzmOnWbs5BbUxMv4PDaPj2w==",
|
"integrity": "sha512-VA/kAqLhkMnRWY2RXdBLyTemR9D4m7MVRy/gyapoq9yvllVPx9WXbvKgnMP2LQp7mFgT/oLFvw58aQKaYTGn3A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/node": {
|
"node_modules/@sentry/node": {
|
||||||
"version": "10.51.0",
|
"version": "10.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.52.0.tgz",
|
||||||
"integrity": "sha512-2yZLRZwS1dKG8/4eOTpGSo/gO/EgmT9aPj6lAzUkRa7bZCTTdW4BraaHU0leX5T94909Qfhbr3W5AVTfDOCKiQ==",
|
"integrity": "sha512-9+p3KJUk3rHO1HOEZuSknP2RgKCJZONDm4HWgkVDtVBtocb66KLtVlMjc59d2/bWP7tM3wc877tpG30quFfU9g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fastify/otel": "0.18.0",
|
"@fastify/otel": "0.18.0",
|
||||||
@@ -870,7 +827,6 @@
|
|||||||
"@opentelemetry/instrumentation-graphql": "0.62.0",
|
"@opentelemetry/instrumentation-graphql": "0.62.0",
|
||||||
"@opentelemetry/instrumentation-hapi": "0.60.0",
|
"@opentelemetry/instrumentation-hapi": "0.60.0",
|
||||||
"@opentelemetry/instrumentation-http": "0.214.0",
|
"@opentelemetry/instrumentation-http": "0.214.0",
|
||||||
"@opentelemetry/instrumentation-ioredis": "0.62.0",
|
|
||||||
"@opentelemetry/instrumentation-kafkajs": "0.23.0",
|
"@opentelemetry/instrumentation-kafkajs": "0.23.0",
|
||||||
"@opentelemetry/instrumentation-knex": "0.58.0",
|
"@opentelemetry/instrumentation-knex": "0.58.0",
|
||||||
"@opentelemetry/instrumentation-koa": "0.62.0",
|
"@opentelemetry/instrumentation-koa": "0.62.0",
|
||||||
@@ -880,14 +836,13 @@
|
|||||||
"@opentelemetry/instrumentation-mysql": "0.60.0",
|
"@opentelemetry/instrumentation-mysql": "0.60.0",
|
||||||
"@opentelemetry/instrumentation-mysql2": "0.60.0",
|
"@opentelemetry/instrumentation-mysql2": "0.60.0",
|
||||||
"@opentelemetry/instrumentation-pg": "0.66.0",
|
"@opentelemetry/instrumentation-pg": "0.66.0",
|
||||||
"@opentelemetry/instrumentation-redis": "0.62.0",
|
|
||||||
"@opentelemetry/instrumentation-tedious": "0.33.0",
|
"@opentelemetry/instrumentation-tedious": "0.33.0",
|
||||||
"@opentelemetry/sdk-trace-base": "^2.6.1",
|
"@opentelemetry/sdk-trace-base": "^2.6.1",
|
||||||
"@opentelemetry/semantic-conventions": "^1.40.0",
|
"@opentelemetry/semantic-conventions": "^1.40.0",
|
||||||
"@prisma/instrumentation": "7.6.0",
|
"@prisma/instrumentation": "7.6.0",
|
||||||
"@sentry/core": "10.51.0",
|
"@sentry/core": "10.52.0",
|
||||||
"@sentry/node-core": "10.51.0",
|
"@sentry/node-core": "10.52.0",
|
||||||
"@sentry/opentelemetry": "10.51.0",
|
"@sentry/opentelemetry": "10.52.0",
|
||||||
"import-in-the-middle": "^3.0.0"
|
"import-in-the-middle": "^3.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -895,13 +850,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/node-core": {
|
"node_modules/@sentry/node-core": {
|
||||||
"version": "10.51.0",
|
"version": "10.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.52.0.tgz",
|
||||||
"integrity": "sha512-VP9DMEzBEuauABrfDHYz/pRYa74M09uRJLz0ls3yel3sKhYHMyCB29ZxbKcciUhD4d33dwgi8DbaPZV2H/wnfQ==",
|
"integrity": "sha512-IG7MBtLRPQ2LuU+kbD14AFZroZgAeUmJQTP1FI/F8n56O31+p+9R703LuBTpvZr6sm+eRYDMWcGYYkfLHRVjwg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/core": "10.51.0",
|
"@sentry/core": "10.52.0",
|
||||||
"@sentry/opentelemetry": "10.51.0",
|
"@sentry/opentelemetry": "10.52.0",
|
||||||
"import-in-the-middle": "^3.0.0"
|
"import-in-the-middle": "^3.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -937,12 +892,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@sentry/opentelemetry": {
|
"node_modules/@sentry/opentelemetry": {
|
||||||
"version": "10.51.0",
|
"version": "10.52.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.51.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.52.0.tgz",
|
||||||
"integrity": "sha512-Qc7AlCE4uhB+SvHLqah4RgR1WdY7wmmr/hx9g/prDP9R1ocshmUEMrZK9qjuwaklW7/fmkFCXI8ETxo5L1bHIA==",
|
"integrity": "sha512-Sc7StsvC0bwhMcgDfTRWUIexO5cNzzKUurvUwtpgQUnxO7AzexU3lkY3yHYDsCbWYAEQMXAgQYQtbcqoh+Ie7g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@sentry/core": "10.51.0"
|
"@sentry/core": "10.52.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "call-me",
|
"name": "call-me",
|
||||||
"version": "1.3.44",
|
"version": "1.3.45",
|
||||||
"description": "Your Go-To for Instant Video Calls",
|
"description": "Your Go-To for Instant Video Calls",
|
||||||
"author": "Miroslav Pejic - miroslav.pejic.85@gmail.com",
|
"author": "Miroslav Pejic - miroslav.pejic.85@gmail.com",
|
||||||
"license": "AGPLv3",
|
"license": "AGPLv3",
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ngrok/ngrok": "1.7.0",
|
"@ngrok/ngrok": "1.7.0",
|
||||||
"@sentry/node": "^10.51.0",
|
"@sentry/node": "^10.52.0",
|
||||||
"axios": "^1.16.0",
|
"axios": "^1.16.0",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"cors": "^2.8.6",
|
"cors": "^2.8.6",
|
||||||
|
|||||||
+43
-4
@@ -90,6 +90,8 @@ let callingTimerId = null; // Timer for calling overlay
|
|||||||
let callingElapsed = 0; // Seconds elapsed while calling
|
let callingElapsed = 0; // Seconds elapsed while calling
|
||||||
let incomingCallData = null; // Pending incoming call data
|
let incomingCallData = null; // Pending incoming call data
|
||||||
let incomingCallTimerId = null; // Auto-decline timer for incoming call
|
let incomingCallTimerId = null; // Auto-decline timer for incoming call
|
||||||
|
let ringTimeout = 30; // Seconds before unanswered call is auto-cancelled/declined (from server)
|
||||||
|
let ringingAudio = null; // Looping ring sound for incoming call
|
||||||
let thisConnection;
|
let thisConnection;
|
||||||
let camera = 'user';
|
let camera = 'user';
|
||||||
let stream;
|
let stream;
|
||||||
@@ -777,6 +779,9 @@ function showCallingOverlay(targetUser) {
|
|||||||
callingTimerId = setInterval(() => {
|
callingTimerId = setInterval(() => {
|
||||||
callingElapsed++;
|
callingElapsed++;
|
||||||
if (callingTimer) callingTimer.textContent = callingElapsed + 's';
|
if (callingTimer) callingTimer.textContent = callingElapsed + 's';
|
||||||
|
if (callingElapsed >= ringTimeout) {
|
||||||
|
handleCancelCall();
|
||||||
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1375,6 +1380,9 @@ function handlePing(data) {
|
|||||||
if (data.pushEnabled !== undefined) {
|
if (data.pushEnabled !== undefined) {
|
||||||
pushEnabled = data.pushEnabled;
|
pushEnabled = data.pushEnabled;
|
||||||
}
|
}
|
||||||
|
if (data.ringTimeout !== undefined) {
|
||||||
|
ringTimeout = data.ringTimeout;
|
||||||
|
}
|
||||||
sendMsg({
|
sendMsg({
|
||||||
type: 'pong',
|
type: 'pong',
|
||||||
message: {
|
message: {
|
||||||
@@ -1717,7 +1725,6 @@ function offerAccept(data) {
|
|||||||
|
|
||||||
incomingCallData = data;
|
incomingCallData = data;
|
||||||
showIncomingCallOverlay(data.from);
|
showIncomingCallOverlay(data.from);
|
||||||
sound('ring');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show incoming call overlay
|
// Show incoming call overlay
|
||||||
@@ -1725,20 +1732,47 @@ function showIncomingCallOverlay(callerName) {
|
|||||||
if (!incomingCallOverlay) return;
|
if (!incomingCallOverlay) return;
|
||||||
if (incomingCallUsername) incomingCallUsername.textContent = callerName;
|
if (incomingCallUsername) incomingCallUsername.textContent = callerName;
|
||||||
|
|
||||||
// Reset timer bar animation
|
// Reset timer bar animation with dynamic duration
|
||||||
if (incomingCallTimer) {
|
if (incomingCallTimer) {
|
||||||
|
incomingCallTimer.style.setProperty('--ring-duration', ringTimeout + 's');
|
||||||
incomingCallTimer.style.animation = 'none';
|
incomingCallTimer.style.animation = 'none';
|
||||||
incomingCallTimer.offsetHeight; // Force reflow
|
incomingCallTimer.offsetHeight; // Force reflow
|
||||||
incomingCallTimer.style.animation = '';
|
incomingCallTimer.style.animation = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start looping ring sound with a 1s gap between plays
|
||||||
|
if (ringingAudio) {
|
||||||
|
ringingAudio.pause();
|
||||||
|
ringingAudio = null;
|
||||||
|
}
|
||||||
|
let ringingDelayTimer = null;
|
||||||
|
function playRing() {
|
||||||
|
if (!ringingAudio) return;
|
||||||
|
ringingAudio.currentTime = 0;
|
||||||
|
ringingAudio.play().catch(() => {});
|
||||||
|
}
|
||||||
|
ringingAudio = new Audio('./assets/ring.wav');
|
||||||
|
ringingAudio.volume = 0.5;
|
||||||
|
ringingAudio.addEventListener('ended', () => {
|
||||||
|
ringingDelayTimer = setTimeout(playRing, 3000);
|
||||||
|
});
|
||||||
|
// Store the delay timer on the audio object so hideIncomingCallOverlay can clear it
|
||||||
|
ringingAudio._delayTimer = null;
|
||||||
|
Object.defineProperty(ringingAudio, '_delayTimer', {
|
||||||
|
get: () => ringingDelayTimer,
|
||||||
|
set: (v) => {
|
||||||
|
ringingDelayTimer = v;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
playRing();
|
||||||
|
|
||||||
incomingCallOverlay.style.display = 'flex';
|
incomingCallOverlay.style.display = 'flex';
|
||||||
|
|
||||||
// Auto-decline after 10 seconds
|
// Auto-decline after ringTimeout seconds
|
||||||
if (incomingCallTimerId) clearTimeout(incomingCallTimerId);
|
if (incomingCallTimerId) clearTimeout(incomingCallTimerId);
|
||||||
incomingCallTimerId = setTimeout(() => {
|
incomingCallTimerId = setTimeout(() => {
|
||||||
handleDeclineIncomingCall();
|
handleDeclineIncomingCall();
|
||||||
}, 10000);
|
}, ringTimeout * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide incoming call overlay
|
// Hide incoming call overlay
|
||||||
@@ -1749,6 +1783,11 @@ function hideIncomingCallOverlay() {
|
|||||||
clearTimeout(incomingCallTimerId);
|
clearTimeout(incomingCallTimerId);
|
||||||
incomingCallTimerId = null;
|
incomingCallTimerId = null;
|
||||||
}
|
}
|
||||||
|
if (ringingAudio) {
|
||||||
|
clearTimeout(ringingAudio._delayTimer);
|
||||||
|
ringingAudio.pause();
|
||||||
|
ringingAudio = null;
|
||||||
|
}
|
||||||
incomingCallData = null;
|
incomingCallData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3010,7 +3010,7 @@ z-index:
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: linear-gradient(90deg, var(--success-color), var(--primary-color));
|
background: linear-gradient(90deg, var(--success-color), var(--primary-color));
|
||||||
animation: incomingTimerBar 10s linear forwards;
|
animation: incomingTimerBar var(--ring-duration, 30s) linear forwards;
|
||||||
transform-origin: left;
|
transform-origin: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user