@iksdev/shard-cli 0.1.48 → 0.1.49

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.
Files changed (2) hide show
  1. package/bin/shard.js +77 -57
  2. package/package.json +1 -1
package/bin/shard.js CHANGED
@@ -702,49 +702,12 @@ async function shareFile(positionals, flags) {
702
702
  if (Number.isFinite(n) && n > 0) createdShareId = n;
703
703
  }
704
704
 
705
- // ── Affichage statut partage actif ─────────────────────────────────────
706
- const WS = 58;
707
- const hr = (l, m, r, col) => `${c(col, l + m.repeat(WS) + r)}`;
708
- const rowS = (content, col) => {
709
- const vis = content.replace(/\x1b\[[0-9;]*m/g, '');
710
- const pad = WS - vis.length;
711
- return `${c(col, '│')}${content}${' '.repeat(Math.max(0, pad))}${c(col, '│')}`;
712
- };
705
+ // Ecran "Partage actif" - affiché après connexion
706
+ printShareActiveScreen(share, fileName, limits, temps);
713
707
 
714
- process.stdout.write('\x1Bc');
715
- console.log('');
716
- console.log(hr('┌', '─', '┐', '\x1b[32m'));
717
- const titleShare = '\x1b[1m\x1b[32m' + ' PARTAGE ACTIF' + '\x1b[0m';
718
- console.log(rowS(titleShare + ' '.repeat(WS - 15), '\x1b[32m'));
719
- console.log(hr('├', '─', '┤', '\x1b[32m'));
720
- console.log(rowS('', '\x1b[32m'));
721
- if (share.url) {
722
- const urlLabel = ' \x1b[90mURL \x1b[0m \x1b[1m\x1b[97m' + share.url + '\x1b[0m';
723
- console.log(rowS(urlLabel, '\x1b[32m'));
724
- }
725
- if (share.token) {
726
- const tokLabel = ' \x1b[90mToken \x1b[0m \x1b[36m' + share.token + '\x1b[0m';
727
- console.log(rowS(tokLabel, '\x1b[32m'));
728
- }
729
- const fileLabel = ' \x1b[90mFichier \x1b[0m \x1b[97m' + fileName + '\x1b[0m';
730
- console.log(rowS(fileLabel, '\x1b[32m'));
731
- const dlLabel = ' \x1b[90mLimite \x1b[0m \x1b[97m' + (limits && limits > 0 ? String(limits) + ' telechargement(s)' : 'illimite') + '\x1b[0m';
732
- console.log(rowS(dlLabel, '\x1b[32m'));
733
- const expLabel = ' \x1b[90mExpire \x1b[0m \x1b[97m' + (temps && temps > 0 ? `dans ${temps} jour(s)` : 'jamais') + '\x1b[0m';
734
- console.log(rowS(expLabel, '\x1b[32m'));
735
- console.log(rowS('', '\x1b[32m'));
736
- console.log(hr('├', '─', '┤', '\x1b[90m'));
737
- const hint = ' \x1b[90mTape \x1b[0m\x1b[1m\x1b[97m q \x1b[0m\x1b[90m + Entree pour cloture le partage et revenir au menu\x1b[0m';
738
- console.log(rowS(hint, '\x1b[90m'));
739
- console.log(hr('└', '─', '┘', '\x1b[90m'));
740
- console.log('');
741
-
742
- // Attend soit la fermeture du socket, soit que l'utilisateur tape 'q'
708
+ // Attend 'q' + Entree ou fermeture du socket
743
709
  await new Promise((resolve) => {
744
- // Fermeture côté serveur
745
710
  relaySocket.on('close', () => resolve('closed'));
746
-
747
- // Écoute clavier : 'q' + Entrée = clôture manuelle
748
711
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
749
712
  const onLine = (line) => {
750
713
  if (line.trim().toLowerCase() === 'q') {
@@ -753,21 +716,15 @@ async function shareFile(positionals, flags) {
753
716
  }
754
717
  };
755
718
  rl.on('line', onLine);
756
- // Nettoyer si le socket se ferme en premier
757
719
  relaySocket.once('close', () => {
758
720
  rl.removeListener('line', onLine);
759
- rl.close();
721
+ try { rl.close(); } catch (_) {}
760
722
  });
761
723
  });
762
724
 
763
- if (heartbeat) {
764
- clearInterval(heartbeat);
765
- heartbeat = null;
766
- }
725
+ if (heartbeat) { clearInterval(heartbeat); heartbeat = null; }
767
726
  await revokeCreatedShare();
768
- for (const sig of stopSignals) {
769
- process.off(sig, stopRelayShare);
770
- }
727
+ for (const sig of stopSignals) process.off(sig, stopRelayShare);
771
728
  closeRelay();
772
729
  return;
773
730
  } catch (error) {
@@ -1209,7 +1166,7 @@ function hr(left = '├', mid = '─', right = '┤', color = C.gray) {
1209
1166
  return c(color, `${left}${mid.repeat(W)}${right}`);
1210
1167
  }
1211
1168
 
1212
- // Ligne avec bordures latérales, contenu centré ou libre
1169
+ // Ligne avec bordures latérales
1213
1170
  function row(content = '', color = C.gray) {
1214
1171
  const vis = strip(content);
1215
1172
  const pad = W - vis.length;
@@ -1223,6 +1180,67 @@ function rowCentered(content, color = C.gray) {
1223
1180
  return row(' '.repeat(l) + content + ' '.repeat(r), color);
1224
1181
  }
1225
1182
 
1183
+ // ── Écran de partage actif ────────────────────────────────────────────────────
1184
+
1185
+ function printShareActiveScreen(share, fileName, limits, temps) {
1186
+ const GRN = '\x1b[32m';
1187
+ const DGRN = '\x1b[90m'; // gris foncé pour les labels
1188
+ const WHT = '\x1b[97m';
1189
+ const BWHT = '\x1b[1m\x1b[97m';
1190
+ const CYN = '\x1b[36m';
1191
+ const RST = '\x1b[0m';
1192
+ const DIM = '\x1b[2m';
1193
+
1194
+ const LABEL_W = 10; // largeur des labels alignés
1195
+
1196
+ // Tronque proprement une valeur si elle dépasse la largeur dispo
1197
+ const valW = W - 2 - LABEL_W - 2; // bordure + label + espace
1198
+ const trunc = (s) => s.length > valW ? s.slice(0, valW - 1) + '…' : s;
1199
+
1200
+ const rowShare = (label, value, valColor = WHT) => {
1201
+ const lbl = ` ${DGRN}${label.padEnd(LABEL_W)}${RST}`;
1202
+ const val = `${valColor}${trunc(value)}${RST}`;
1203
+ const vis = strip(lbl + val);
1204
+ const pad = W - vis.length;
1205
+ return `${GRN}│${RST}${lbl}${val}${' '.repeat(Math.max(0, pad))}${GRN}│${RST}`;
1206
+ };
1207
+
1208
+ const dlLabel = limits && limits > 0 ? `${limits} telechargement(s)` : 'illimite';
1209
+ const expLabel = temps && temps > 0 ? `dans ${temps} jour(s)` : 'jamais';
1210
+ const dot = ` ${DIM}·${RST} `;
1211
+
1212
+ clearScreen();
1213
+ console.log('');
1214
+ // En-tête
1215
+ console.log(`${GRN}┌${'─'.repeat(W)}┐${RST}`);
1216
+
1217
+ const badge = `${GRN}▸${RST} ${BWHT}PARTAGE ACTIF${RST}`;
1218
+ const badgeVis = strip(badge);
1219
+ const bL = Math.floor((W - badgeVis.length) / 2);
1220
+ const bR = W - badgeVis.length - bL;
1221
+ console.log(`${GRN}│${RST}${' '.repeat(bL)}${badge}${' '.repeat(bR)}${GRN}│${RST}`);
1222
+
1223
+ console.log(`${GRN}├${'─'.repeat(W)}┤${RST}`);
1224
+
1225
+ // Infos
1226
+ console.log(`${GRN}│${RST}${' '.repeat(W)}${GRN}│${RST}`);
1227
+ if (share.url) console.log(rowShare('URL', share.url, BWHT));
1228
+ if (share.token) console.log(rowShare('Token', share.token, CYN));
1229
+ console.log(rowShare('Fichier', fileName, WHT));
1230
+ console.log(rowShare('Limite', dlLabel, WHT));
1231
+ console.log(rowShare('Expire', expLabel, WHT));
1232
+ console.log(`${GRN}│${RST}${' '.repeat(W)}${GRN}│${RST}`);
1233
+
1234
+ // Footer
1235
+ console.log(`${DGRN}├${'─'.repeat(W)}┤${RST}`);
1236
+ const hint = ` Tape ${BWHT}q${RST}${DGRN} + Entree pour cloture et revenir au menu${RST}`;
1237
+ const hintVis = strip(hint);
1238
+ const hPad = W - hintVis.length;
1239
+ console.log(`${DGRN}│${RST}${hint}${' '.repeat(Math.max(0, hPad))}${DGRN}│${RST}`);
1240
+ console.log(`${DGRN}└${'─'.repeat(W)}┘${RST}`);
1241
+ console.log('');
1242
+ }
1243
+
1226
1244
  function printPanel(username, plan, statusMsg) {
1227
1245
  const now = new Date();
1228
1246
  const timeStr = now.toLocaleTimeString('fr-FR', { hour: '2-digit', minute: '2-digit' });
@@ -1332,24 +1350,26 @@ async function panelShare() {
1332
1350
  if (parseInt(limits, 10) > 0) flags.limits = limits;
1333
1351
  if (parseInt(temps, 10) > 0) flags.temps = temps;
1334
1352
 
1353
+ // Écran de chargement pendant la connexion au relay
1335
1354
  clearScreen();
1336
- printSubHeader('Partage en cours...');
1337
- console.log(` ${c(C.gray, 'Connexion au relay...')}\n`);
1355
+ printSubHeader('Connexion au relay...');
1356
+ console.log(` ${c(C.gray, 'Initialisation du partage, patiente...')}\n`);
1338
1357
 
1339
1358
  try {
1340
1359
  await shareFile([target], flags);
1341
- // shareFile retourne quand l'utilisateur tape 'q' ou que le socket se ferme
1342
- printSuccess('Partage cloture.');
1360
+ // Retour au menu : shareFile a déjà révoqué et fermé
1361
+ clearScreen();
1362
+ printSubHeader('Partager un fichier');
1363
+ printSuccess('Partage cloture avec succes.');
1343
1364
  } catch (err) {
1365
+ clearScreen();
1366
+ printSubHeader('Partager un fichier');
1344
1367
  if (err?.data?.code === 'PLAN_FILE_LIMIT_EXCEEDED') {
1345
1368
  printPlanLimitBox(err);
1346
1369
  } else {
1347
1370
  printError(err.message);
1348
1371
  }
1349
- await pressEnter();
1350
- return;
1351
1372
  }
1352
-
1353
1373
  await pressEnter();
1354
1374
  }
1355
1375
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iksdev/shard-cli",
3
- "version": "0.1.48",
3
+ "version": "0.1.49",
4
4
  "description": "CLI pour synchroniser un dossier local avec Shard",
5
5
  "bin": {
6
6
  "shard": "bin/shard.js"