CH-J SM Mobilepamamahala ng server sa pamamagitan ng SSH
Menu
Nailathalang source

CH-J SM Mobile

I-browse ang mga direktoryo at file ng isang partikular na release ng application.

I-download ang source ZIP
CH-J / SM Mobile 175 file
sm-mobile-20261016T185235Z-8e93ecc1b59a Idinagdag: · Binuo:
export_sheet.dart Idinagdag: Hindi naitala ang petsa 4.0 KB · 128 linya
Code I-download ang file
1import 'dart:convert';
2import 'dart:io';
3import 'package:flutter/material.dart';
4import 'package:flutter/services.dart';
5import 'package:path_provider/path_provider.dart';
6import 'package:share_plus/share_plus.dart';
7import '../core/app_controller.dart';
8import '../l10n/strings.dart';
9import '../models/server_profile.dart';
10import '../services/net/measure.dart';
11import 'common.dart';
13const _mime = {
14 ReportFormat.txt: 'text/plain',
15 ReportFormat.csv: 'text/csv',
16 ReportFormat.json: 'application/json',
17};
19/// Offers a report as text on the clipboard, through the share sheet, or
20/// saved to a place the user picks on the device. Nothing is sent anywhere
21/// without that explicit choice.
22Future<void> showExportSheet(
23 BuildContext context,
24 AppController c, {
25 required String baseName,
26 required String Function(ReportFormat) build,
27}) async {
28 final origin = _origin(context);
29 final choice = await showModalBottomSheet<(String, ReportFormat)>(
30 context: context,
31 isScrollControlled: true,
32 builder: (ctx) => SafeArea(
33 child: SingleChildScrollView(
34 child: Column(
35 mainAxisSize: MainAxisSize.min,
36 children: [
37 ListTile(
38 title: Text(
39 ctx.tr('exportResults'),
40 style: Theme.of(ctx).textTheme.titleMedium,
41 ),
42 ),
43 for (final f in ReportFormat.values) ...[
44 ListTile(
45 leading: const Icon(Icons.save_alt),
46 title: Text(
47 '${ctx.tr('saveToDevice')} · ${f.name.toUpperCase()}',
48 ),
49 onTap: () => Navigator.pop(ctx, ('save', f)),
50 ),
51 ListTile(
52 leading: const Icon(Icons.ios_share),
53 title: Text('${ctx.tr('shareFile')} · ${f.name.toUpperCase()}'),
54 onTap: () => Navigator.pop(ctx, ('share', f)),
55 ),
56 ],
57 ListTile(
58 leading: const Icon(Icons.copy),
59 title: Text('${ctx.tr('copyResults')} · TXT'),
60 onTap: () => Navigator.pop(ctx, ('copy', ReportFormat.txt)),
61 ),
62 ],
63 ),
64 ),
65 ),
66 );
67 if (choice == null || !context.mounted) return;
68 final (action, format) = choice;
69 final text = build(format);
70 final name = '$baseName.${format.name}';
71 try {
72 switch (action) {
73 case 'copy':
74 await Clipboard.setData(ClipboardData(text: text));
75 if (context.mounted) _done(context, 'copied');
76 case 'save':
77 final saved = await c.withSystemDialog(
78 () =>
79 c.documents.saveAs(name, utf8.encode(text), mime: _mime[format]),
80 );
81 if (saved != null && context.mounted) _done(context, 'savedToDevice');
82 case 'share':
83 await shareText(c, name, text, origin);
84 }
85 } catch (e) {
86 if (context.mounted) showFailure(context, e);
87 }
90Rect _origin(BuildContext context) {
91 final box = context.findRenderObject() as RenderBox?;
92 final o = box?.localToGlobal(Offset.zero) ?? Offset.zero;
93 return Rect.fromLTWH(o.dx, o.dy, 1, 1);
96void _done(BuildContext context, String key) => ScaffoldMessenger.of(
97 context,
98).showSnackBar(SnackBar(content: Text(context.tr(key))));
100/// Shares [text] as a file named [name] through the system share sheet. The
101/// temporary copy is deleted afterwards.
102Future<void> shareText(
103 AppController c,
104 String name,
105 String text,
106 Rect origin,
107) => shareBytes(c, name, utf8.encode(text), origin);
109Future<void> shareBytes(
110 AppController c,
111 String name,
112 List<int> bytes,
113 Rect origin,
114) async {
115 final temp = await getTemporaryDirectory();
116 final dir = await Directory('${temp.path}/sm-transfer-${newId()}').create();
117 try {
118 final file = File('${dir.path}/$name');
119 await file.writeAsBytes(bytes, flush: true);
120 await c.withSystemDialog(
121 () => SharePlus.instance.share(
122 ShareParams(files: [XFile(file.path)], sharePositionOrigin: origin),
123 ),
124 );
125 } finally {
126 if (await dir.exists()) await dir.delete(recursive: true);
127 }
SHA-25676b8771a8ec39151389cc01d2aeb58026fc681d5c9537138b60164d9ed5092e9

CH-J Proprietary Software License 1.14 · Ibinibigay ang source sa ilalim ng CH-J Proprietary Software License 1.14. Hindi binabago ng pagiging available nito ang mga tuntunin ng lisensya at hindi ito nagbibigay ng karagdagang karapatan.

SHA-256 ng archive46e427a43e87af091004f36145590bda8fe90086dfb0f631afeb5029fb0b5655
Mga file