mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-05 01:27:49 +08:00
Compare commits
8 Commits
f0050dd6e6
...
2.0.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ad130567e | ||
|
|
7eb21bc5a2 | ||
|
|
ea4316a847 | ||
|
|
2bbc97a950 | ||
|
|
0178d105ba | ||
|
|
771fa75f48 | ||
|
|
82483b33fc | ||
|
|
886c53c7d8 |
2
.github/workflows/mac.yml
vendored
2
.github/workflows/mac.yml
vendored
@@ -13,7 +13,7 @@ on:
|
||||
jobs:
|
||||
build-mac-app:
|
||||
name: Release Mac
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-26
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
|
||||
@@ -131,5 +131,13 @@
|
||||
</array>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<false/>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>需要访问本地网络以发现和连接 DLNA 投屏设备</string>
|
||||
<key>NSBonjourServices</key>
|
||||
<array>
|
||||
<string>_ssdp._udp</string>
|
||||
<string>_upnp._tcp</string>
|
||||
<string>_http._tcp</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -10,23 +10,21 @@ class CustomToast extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final colorScheme = ColorScheme.of(context);
|
||||
return Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.viewPaddingOf(context).bottom + 30,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primaryContainer.withValues(
|
||||
alpha: toastOpacity,
|
||||
),
|
||||
color: colorScheme.primaryContainer.withValues(alpha: toastOpacity),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
child: Text(
|
||||
msg,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
color: colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -41,7 +39,7 @@ class LoadingWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final ThemeData theme = Theme.of(context);
|
||||
final theme = Theme.of(context);
|
||||
final onSurfaceVariant = theme.colorScheme.onSurfaceVariant;
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 20),
|
||||
@@ -58,7 +56,6 @@ class LoadingWidget extends StatelessWidget {
|
||||
strokeWidth: 3,
|
||||
valueColor: AlwaysStoppedAnimation(onSurfaceVariant),
|
||||
),
|
||||
|
||||
//msg
|
||||
Text(msg, style: TextStyle(color: onSurfaceVariant)),
|
||||
],
|
||||
|
||||
@@ -217,8 +217,8 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
RefreshIndicatorStatus? _status;
|
||||
late Future<void> _pendingRefreshFuture;
|
||||
double? _dragOffset;
|
||||
late Color _effectiveValueColor =
|
||||
widget.color ?? Theme.of(context).colorScheme.primary;
|
||||
late Color _effectiveValueColor;
|
||||
// late Color _backgroundColor;
|
||||
|
||||
static final Animatable<double> _threeQuarterTween = Tween<double>(
|
||||
begin: 0.0,
|
||||
@@ -274,9 +274,10 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
}
|
||||
|
||||
void _setupColorTween() {
|
||||
final colorScheme = ColorScheme.of(context);
|
||||
// _backgroundColor = colorScheme.surfaceContainerHighest;
|
||||
// Reset the current value color.
|
||||
_effectiveValueColor =
|
||||
widget.color ?? Theme.of(context).colorScheme.primary;
|
||||
_effectiveValueColor = widget.color ?? colorScheme.primary;
|
||||
final Color color = _effectiveValueColor;
|
||||
if (color.a == 0) {
|
||||
// Set an always stopped animation instead of a driven tween.
|
||||
@@ -558,14 +559,52 @@ class RefreshIndicatorState extends State<RefreshIndicator>
|
||||
}
|
||||
|
||||
bool _onDrag(double offset, double viewportDimension) {
|
||||
if (_positionController.value > 0.0 &&
|
||||
_status == RefreshIndicatorStatus.drag) {
|
||||
if (_positionController.value > 0.0 && _status == .drag) {
|
||||
_dragOffset = _dragOffset! + offset;
|
||||
_checkDragOffset(viewportDimension);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// late final _refreshKey = GlobalKey();
|
||||
// Widget _m3eRefreshProgressIndicator(bool showIndeterminateIndicator) {
|
||||
// const indicatorMargin = EdgeInsets.all(4);
|
||||
// const indicatorPadding = EdgeInsets.all(6);
|
||||
// const indicatorSize = 41.0;
|
||||
|
||||
// final progress = _value.value;
|
||||
// return Padding(
|
||||
// padding: indicatorMargin,
|
||||
// child: SizedBox(
|
||||
// width: indicatorSize,
|
||||
// height: indicatorSize,
|
||||
// child: Material(
|
||||
// type: MaterialType.circle,
|
||||
// color: _backgroundColor,
|
||||
// elevation: widget.elevation,
|
||||
// child: Padding(
|
||||
// padding: indicatorPadding,
|
||||
// child: showIndeterminateIndicator
|
||||
// ? M3ELoadingIndicator(
|
||||
// childKey: _refreshKey,
|
||||
// color: _effectiveValueColor,
|
||||
// morphs: Morphs.refreshMorphs,
|
||||
// size: null,
|
||||
// )
|
||||
// : RawM3ELoadingIndicator(
|
||||
// key: _refreshKey,
|
||||
// morph: Morphs.manualMorph,
|
||||
// progress: progress,
|
||||
// angle: -progress * math.pi,
|
||||
// color: _valueColor.value!,
|
||||
// size: null,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
// ignore: camel_case_types
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
import 'dart:math' show pi;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/semantics.dart' show SemanticsConfiguration;
|
||||
|
||||
///
|
||||
/// created by dom on 2026/02/14
|
||||
@@ -73,6 +74,7 @@ class RenderLoadingIndicator extends RenderBox {
|
||||
if (_progress == value) return;
|
||||
_progress = value;
|
||||
markNeedsPaint();
|
||||
markNeedsSemanticsUpdate();
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -119,6 +121,16 @@ class RenderLoadingIndicator extends RenderBox {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void describeSemanticsConfiguration(SemanticsConfiguration config) {
|
||||
super.describeSemanticsConfiguration(config);
|
||||
config
|
||||
..role = .progressBar
|
||||
..minValue = '0'
|
||||
..maxValue = '100'
|
||||
..value = (_progress * 100).round().toString();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get isRepaintBoundary => true;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ import 'package:flutter/material.dart';
|
||||
|
||||
const Widget m3eLoading = Center(child: M3ELoadingIndicator());
|
||||
|
||||
const Widget circularLoading = Center(child: CircularProgressIndicator());
|
||||
|
||||
const Widget linearLoading = SliverToBoxAdapter(
|
||||
child: LinearProgressIndicator(),
|
||||
);
|
||||
|
||||
@@ -17,14 +17,27 @@
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/morphs.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/physics.dart' show SpringSimulation;
|
||||
import 'package:flutter/semantics.dart';
|
||||
import 'package:material_new_shapes/material_new_shapes.dart';
|
||||
|
||||
/// reimplement of https://github.com/EmilyMoonstone/material_3_expressive/tree/main/packages/loading_indicator_m3e
|
||||
|
||||
class M3ELoadingIndicator extends StatefulWidget {
|
||||
const M3ELoadingIndicator({super.key});
|
||||
const M3ELoadingIndicator({
|
||||
super.key,
|
||||
// this.childKey,
|
||||
this.morphs,
|
||||
this.color,
|
||||
this.size = const Size.square(40),
|
||||
});
|
||||
final List<Morph>? morphs;
|
||||
|
||||
final Color? color;
|
||||
final Size size;
|
||||
// final Key? childKey;
|
||||
|
||||
@override
|
||||
State<M3ELoadingIndicator> createState() => _M3ELoadingIndicatorState();
|
||||
@@ -32,42 +45,25 @@ class M3ELoadingIndicator extends StatefulWidget {
|
||||
|
||||
class _M3ELoadingIndicatorState extends State<M3ELoadingIndicator>
|
||||
with SingleTickerProviderStateMixin {
|
||||
static final List<Morph> _morphs = () {
|
||||
final List<RoundedPolygon> shapes = [
|
||||
MaterialShapes.softBurst,
|
||||
MaterialShapes.cookie9Sided,
|
||||
MaterialShapes.pentagon,
|
||||
MaterialShapes.pill,
|
||||
MaterialShapes.sunny,
|
||||
MaterialShapes.cookie4Sided,
|
||||
MaterialShapes.oval,
|
||||
];
|
||||
return [
|
||||
for (var i = 0; i < shapes.length; i++)
|
||||
Morph(
|
||||
shapes[i],
|
||||
shapes[(i + 1) % shapes.length],
|
||||
),
|
||||
];
|
||||
}();
|
||||
|
||||
static const int _morphIntervalMs = 650;
|
||||
static const double _fullRotation = 360.0;
|
||||
static const double _fullRotation = 2 * math.pi;
|
||||
static const int _globalRotationDurationMs = 4666;
|
||||
static const double _quarterRotation = _fullRotation / 4;
|
||||
|
||||
late final List<Morph> _morphs;
|
||||
late final AnimationController _controller;
|
||||
|
||||
int _morphIndex = 1;
|
||||
|
||||
double _morphRotationTargetAngle = _quarterRotation;
|
||||
double _morphRotationTarget = _quarterRotation;
|
||||
|
||||
final _morphAnimationSpec = SpringSimulation(
|
||||
static final _morphAnimationSpec = SpringSimulation(
|
||||
SpringDescription.withDampingRatio(ratio: 0.6, stiffness: 200.0, mass: 1.0),
|
||||
0.0,
|
||||
1.0,
|
||||
5.0,
|
||||
snapToEnd: true,
|
||||
// tolerance: const Tolerance(velocity: 0.1, distance: 0.1),
|
||||
);
|
||||
|
||||
void _statusListener(AnimationStatus status) {
|
||||
@@ -78,23 +74,21 @@ class _M3ELoadingIndicatorState extends State<M3ELoadingIndicator>
|
||||
|
||||
void _startAnimation() {
|
||||
_morphIndex++;
|
||||
_morphRotationTargetAngle =
|
||||
(_morphRotationTargetAngle + _quarterRotation) % _fullRotation;
|
||||
_controller
|
||||
..value = 0.0
|
||||
..animateWith(_morphAnimationSpec);
|
||||
_morphRotationTarget =
|
||||
(_morphRotationTarget + _quarterRotation) % _fullRotation;
|
||||
_controller.animateWith(_morphAnimationSpec);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_morphs = widget.morphs ?? Morphs.loadingMorphs;
|
||||
_controller =
|
||||
AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: _morphIntervalMs),
|
||||
)
|
||||
..addStatusListener(_statusListener)
|
||||
..value = 0.0
|
||||
..animateWith(_morphAnimationSpec);
|
||||
}
|
||||
|
||||
@@ -110,82 +104,86 @@ class _M3ELoadingIndicatorState extends State<M3ELoadingIndicator>
|
||||
final elapsedInMs =
|
||||
_morphIntervalMs * (_morphIndex - 1) +
|
||||
(_controller.lastElapsedDuration?.inMilliseconds ?? 0);
|
||||
final globalRotationControllerValue =
|
||||
(elapsedInMs % _globalRotationDurationMs) / _globalRotationDurationMs;
|
||||
final globalRotationDegrees = globalRotationControllerValue * _fullRotation;
|
||||
final totalRotationDegrees =
|
||||
progress * _quarterRotation +
|
||||
_morphRotationTargetAngle +
|
||||
globalRotationDegrees;
|
||||
return totalRotationDegrees * (math.pi / 180.0);
|
||||
final globalRotation =
|
||||
(elapsedInMs % _globalRotationDurationMs) /
|
||||
_globalRotationDurationMs *
|
||||
_fullRotation;
|
||||
|
||||
return progress * _quarterRotation + _morphRotationTarget + globalRotation;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final color = Theme.of(context).colorScheme.secondaryFixedDim;
|
||||
final color = widget.color ?? ColorScheme.of(context).secondaryFixedDim;
|
||||
return AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (context, child) {
|
||||
final progress = _controller.value;
|
||||
return _M3ELoadingIndicator(
|
||||
return RawM3ELoadingIndicator(
|
||||
// key: widget.childKey,
|
||||
morph: _morphs[_morphIndex % _morphs.length],
|
||||
progress: progress,
|
||||
angle: _calcAngle(progress),
|
||||
color: color,
|
||||
size: widget.size,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _M3ELoadingIndicator extends LeafRenderObjectWidget {
|
||||
const _M3ELoadingIndicator({
|
||||
class RawM3ELoadingIndicator extends LeafRenderObjectWidget {
|
||||
const RawM3ELoadingIndicator({
|
||||
super.key,
|
||||
required this.morph,
|
||||
required this.progress,
|
||||
required this.angle,
|
||||
required this.color,
|
||||
required this.size,
|
||||
});
|
||||
|
||||
final Morph morph;
|
||||
|
||||
final double progress;
|
||||
|
||||
final double angle;
|
||||
|
||||
final Color color;
|
||||
final Size size;
|
||||
|
||||
@override
|
||||
RenderObject createRenderObject(BuildContext context) {
|
||||
return _RenderM3ELoadingIndicator(
|
||||
return RenderM3ELoadingIndicator(
|
||||
morph: morph,
|
||||
progress: progress,
|
||||
angle: angle,
|
||||
color: color,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void updateRenderObject(
|
||||
BuildContext context,
|
||||
_RenderM3ELoadingIndicator renderObject,
|
||||
RenderM3ELoadingIndicator renderObject,
|
||||
) {
|
||||
renderObject
|
||||
..morph = morph
|
||||
..progress = progress
|
||||
..angle = angle
|
||||
..color = color;
|
||||
..color = color
|
||||
..preferredSize = size;
|
||||
}
|
||||
}
|
||||
|
||||
class _RenderM3ELoadingIndicator extends RenderBox {
|
||||
_RenderM3ELoadingIndicator({
|
||||
class RenderM3ELoadingIndicator extends RenderBox {
|
||||
RenderM3ELoadingIndicator({
|
||||
required Morph morph,
|
||||
required double progress,
|
||||
required double angle,
|
||||
required Color color,
|
||||
required Size size,
|
||||
}) : _morph = morph,
|
||||
_progress = progress,
|
||||
_angle = angle,
|
||||
_preferredSize = size,
|
||||
_color = color,
|
||||
_paint = Paint()
|
||||
..style = PaintingStyle.fill
|
||||
@@ -223,20 +221,38 @@ class _RenderM3ELoadingIndicator extends RenderBox {
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Size _preferredSize;
|
||||
set preferredSize(Size value) {
|
||||
if (_preferredSize == value) return;
|
||||
_preferredSize = size;
|
||||
markNeedsLayout();
|
||||
}
|
||||
|
||||
@override
|
||||
Size computeDryLayout(covariant BoxConstraints constraints) {
|
||||
return constraints.constrain(_preferredSize);
|
||||
}
|
||||
|
||||
@override
|
||||
void performLayout() {
|
||||
size = constraints.constrainDimensions(40, 40);
|
||||
size = computeDryLayout(constraints);
|
||||
}
|
||||
|
||||
@override
|
||||
void describeSemanticsConfiguration(SemanticsConfiguration config) {
|
||||
super.describeSemanticsConfiguration(config);
|
||||
config.role = .loadingSpinner;
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(PaintingContext context, Offset offset) {
|
||||
final width = size.width;
|
||||
final value = size.width / 2;
|
||||
final matrix = Matrix4.identity()
|
||||
..translateByDouble(offset.dx + value, offset.dy + value, 0.0, 1.0)
|
||||
..rotateZ(angle)
|
||||
..translateByDouble(-value, -value, 0.0, 1.0)
|
||||
..scaleByDouble(width, width, width, 1.0);
|
||||
final matrix =
|
||||
Matrix4.translationValues(offset.dx + value, offset.dy + value, 0.0)
|
||||
..rotateZ(angle)
|
||||
..translateByDouble(-value, -value, 0.0, 1.0)
|
||||
..scaleByDouble(width, width, width, 1.0);
|
||||
final path = morph.toPath(progress: progress).transform(matrix.storage);
|
||||
|
||||
context.canvas.drawPath(path, _paint);
|
||||
|
||||
41
lib/common/widgets/loading_widget/morphs.dart
Normal file
41
lib/common/widgets/loading_widget/morphs.dart
Normal file
@@ -0,0 +1,41 @@
|
||||
import 'package:material_new_shapes/material_new_shapes.dart';
|
||||
|
||||
abstract final class Morphs {
|
||||
static List<Morph> buildMorph(
|
||||
List<RoundedPolygon> shapes, {
|
||||
bool loop = true,
|
||||
}) {
|
||||
assert(shapes.length >= 2);
|
||||
return [
|
||||
for (var i = 0; i < shapes.length - 1; i++)
|
||||
Morph(shapes[i], shapes[i + 1]),
|
||||
if (loop) Morph(shapes[shapes.length - 1], shapes[0]),
|
||||
];
|
||||
}
|
||||
|
||||
static final loadingMorphs = buildMorph([
|
||||
MaterialShapes.softBurst,
|
||||
MaterialShapes.cookie9Sided,
|
||||
MaterialShapes.pentagon,
|
||||
MaterialShapes.pill,
|
||||
MaterialShapes.sunny,
|
||||
MaterialShapes.cookie4Sided,
|
||||
MaterialShapes.oval,
|
||||
]);
|
||||
|
||||
// static final refreshMorphs = buildMorph([
|
||||
// MaterialShapes.softBurst,
|
||||
// MaterialShapes.cookie9Sided,
|
||||
// MaterialShapes.gem,
|
||||
// MaterialShapes.flower,
|
||||
// MaterialShapes.sunny,
|
||||
// MaterialShapes.cookie4Sided,
|
||||
// MaterialShapes.oval,
|
||||
// MaterialShapes.cookie12Sided,
|
||||
// ]);
|
||||
|
||||
// static final manualMorph = Morph(
|
||||
// MaterialShapes.circle,
|
||||
// MaterialShapes.softBurst,
|
||||
// );
|
||||
}
|
||||
@@ -3,7 +3,7 @@ class BaseEmote {
|
||||
late String emoticonUnique;
|
||||
late double width;
|
||||
late double height;
|
||||
late final isUpower = emoticonUnique.startsWith('upower_');
|
||||
late final isOfficial = emoticonUnique.startsWith('official_');
|
||||
|
||||
BaseEmote.fromJson(Map<String, dynamic> json) {
|
||||
url = json['url'];
|
||||
|
||||
@@ -181,21 +181,23 @@ class AuthorPanel extends StatelessWidget {
|
||||
Positioned(
|
||||
top: 0,
|
||||
right: 0,
|
||||
height: height,
|
||||
child: CachedNetworkImage(
|
||||
height: height,
|
||||
memCacheHeight: height.cacheSize(context),
|
||||
imageUrl: ImageUtils.safeThumbnailUrl(
|
||||
moduleAuthor.decorate!.cardUrl,
|
||||
bottom: 0,
|
||||
child: Center(
|
||||
child: CachedNetworkImage(
|
||||
height: height,
|
||||
memCacheHeight: height.cacheSize(context),
|
||||
imageUrl: ImageUtils.safeThumbnailUrl(
|
||||
moduleAuthor.decorate!.cardUrl,
|
||||
),
|
||||
placeholder: (_, _) => const SizedBox.shrink(),
|
||||
),
|
||||
placeholder: (_, _) => const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
if (moduleAuthor.decorate!.fan?.numStr?.isNotEmpty == true)
|
||||
Positioned(
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: height,
|
||||
height: height,
|
||||
child: Center(
|
||||
child: Text(
|
||||
moduleAuthor.decorate!.fan!.numStr!.toString(),
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:PiliPlus/common/widgets/flutter/popup_menu.dart';
|
||||
import 'package:PiliPlus/common/widgets/gesture/tap_gesture_recognizer.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/http/live.dart';
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models_new/live/live_danmaku/danmaku_msg.dart';
|
||||
import 'package:PiliPlus/models_new/live/live_superchat/item.dart';
|
||||
import 'package:PiliPlus/pages/live_room/controller.dart';
|
||||
@@ -241,14 +240,20 @@ class LiveRoomChatPanel extends StatelessWidget {
|
||||
InlineSpan _buildMsg(double devicePixelRatio, DanmakuMsg obj) {
|
||||
final uemote = obj.uemote;
|
||||
if (uemote != null) {
|
||||
// "room_{{room_id}}_{{int}}" or "upower_[{{emote}}]"
|
||||
final isUpower = uemote.isUpower;
|
||||
// "room_{{room_id}}_{{int}}" , "upower_[{{emote}}]" , "official_{{int}}"
|
||||
final double width, height;
|
||||
if (uemote.isOfficial) {
|
||||
width = uemote.width / devicePixelRatio;
|
||||
height = uemote.height / devicePixelRatio;
|
||||
} else {
|
||||
width = height = 162.0 / devicePixelRatio;
|
||||
}
|
||||
return WidgetSpan(
|
||||
child: NetworkImgLayer(
|
||||
src: uemote.url,
|
||||
type: ImageType.emote,
|
||||
width: isUpower ? uemote.width : uemote.width / devicePixelRatio,
|
||||
height: isUpower ? uemote.height : uemote.height / devicePixelRatio,
|
||||
type: .emote,
|
||||
width: width,
|
||||
height: height,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -265,7 +270,7 @@ class LiveRoomChatPanel extends StatelessWidget {
|
||||
WidgetSpan(
|
||||
child: NetworkImgLayer(
|
||||
src: emote.url,
|
||||
type: ImageType.emote,
|
||||
type: .emote,
|
||||
width: emote.width,
|
||||
height: emote.height,
|
||||
),
|
||||
|
||||
@@ -73,3 +73,10 @@ foreach ($patch in $patches) {
|
||||
Write-Host "$patch applied"
|
||||
}
|
||||
}
|
||||
|
||||
# TODO: remove
|
||||
if ($platform.ToLower() -eq "android") {
|
||||
"69e31205362b4e59b7eb89b24797e687b4b67afe" | Set-Content -Path .\bin\internal\engine.version
|
||||
Remove-Item -Path ".\bin\cache" -Recurse -Force
|
||||
flutter --version
|
||||
}
|
||||
@@ -28,5 +28,13 @@
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>需要访问本地网络以发现和连接 DLNA 投屏设备</string>
|
||||
<key>NSBonjourServices</key>
|
||||
<array>
|
||||
<string>_ssdp._udp</string>
|
||||
<string>_upnp._tcp</string>
|
||||
<string>_http._tcp</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
28
pubspec.lock
28
pubspec.lock
@@ -320,18 +320,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: connectivity_plus
|
||||
sha256: "33bae12a398f841c6cda09d1064212957265869104c478e5ad51e2fb26c3973c"
|
||||
sha256: b8fe52979ff12432ecf8f0abf6ff70410b1bb734be1c9e4f2f86807ad7166c79
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
version: "7.1.0"
|
||||
connectivity_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: connectivity_plus_platform_interface
|
||||
sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204"
|
||||
sha256: "3c09627c536d22fd24691a905cdd8b14520de69da52c7a97499c8be5284a32ed"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "2.1.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -400,10 +400,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c"
|
||||
sha256: b4fed1b2835da9d670d7bed7db79ae2a94b0f5ad6312268158a9b5479abbacdd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.3.0"
|
||||
version: "12.4.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -906,10 +906,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image_cropper
|
||||
sha256: "2cd06f097b5bd18ff77d3f80fadef83e270ea23c82906bbf17febc3db8d68ec6"
|
||||
sha256: d2555be1ec4b7b12fc502ede481c846ad44578fbb0748debd4c648b25ca07cad
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.1.0"
|
||||
version: "12.1.1"
|
||||
image_cropper_for_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1283,10 +1283,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
|
||||
sha256: "468c26b4254ab01979fa5e4a98cb343ea3631b9acee6f21028997419a80e1a20"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
version: "9.0.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1579,10 +1579,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: share_plus
|
||||
sha256: "14c8860d4de93d3a7e53af51bff479598c4e999605290756bbbe45cf65b37840"
|
||||
sha256: "223873d106614442ea6f20db5a038685cc5b32a2fba81cdecaefbbae0523f7fa"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.0.1"
|
||||
version: "12.0.2"
|
||||
share_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1905,10 +1905,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_graphics
|
||||
sha256: "7076216a10d5c390315fbe536a30f1254c341e7543e6c4c8a815e591307772b1"
|
||||
sha256: "81da85e9ca8885ade47f9685b953cb098970d11be4821ac765580a6607ea4373"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.20"
|
||||
version: "1.1.21"
|
||||
vector_graphics_codec:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -17,7 +17,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
# update when release
|
||||
version: 2.0.1+1
|
||||
version: 2.0.2+1
|
||||
|
||||
environment:
|
||||
sdk: ">=3.10.0"
|
||||
|
||||
Reference in New Issue
Block a user