mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
@@ -1 +1 @@
|
|||||||
include: package:flutter_lints/flutter.yaml
|
include: ../../analysis_options.yaml
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
export 'wonky_char.dart';
|
|
||||||
export 'wonky_anim_palette.dart';
|
|
||||||
export 'rotator_puzzle.dart';
|
|
||||||
export 'lightboxed_panel.dart';
|
|
||||||
export 'fragment_shaded.dart';
|
export 'fragment_shaded.dart';
|
||||||
|
export 'lightboxed_panel.dart';
|
||||||
|
export 'rotator_puzzle.dart';
|
||||||
|
export 'wonky_anim_palette.dart';
|
||||||
|
export 'wonky_char.dart';
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class FragmentShadedState extends State<FragmentShaded>
|
|||||||
initializeFragmentProgramsAndBuilder();
|
initializeFragmentProgramsAndBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeFragmentProgramsAndBuilder() async {
|
Future<void> initializeFragmentProgramsAndBuilder() async {
|
||||||
if (FragmentShaded.fragmentPrograms.isEmpty) {
|
if (FragmentShaded.fragmentPrograms.isEmpty) {
|
||||||
for (String s in FragmentShaded.fragmentProgramNames) {
|
for (String s in FragmentShaded.fragmentProgramNames) {
|
||||||
FragmentShaded.fragmentPrograms[s] =
|
FragmentShaded.fragmentPrograms[s] =
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class LightboxedPanel extends StatefulWidget {
|
|||||||
final Color cardBgColor;
|
final Color cardBgColor;
|
||||||
|
|
||||||
const LightboxedPanel({
|
const LightboxedPanel({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.pageConfig,
|
required this.pageConfig,
|
||||||
required this.content,
|
required this.content,
|
||||||
this.onDismiss,
|
this.onDismiss,
|
||||||
@@ -27,7 +27,7 @@ class LightboxedPanel extends StatefulWidget {
|
|||||||
this.buildButton = true,
|
this.buildButton = true,
|
||||||
this.lightBoxBgColor = const Color.fromARGB(200, 255, 255, 255),
|
this.lightBoxBgColor = const Color.fromARGB(200, 255, 255, 255),
|
||||||
this.cardBgColor = Colors.white,
|
this.cardBgColor = Colors.white,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<LightboxedPanel> createState() => _LightboxedPanelState();
|
State<LightboxedPanel> createState() => _LightboxedPanelState();
|
||||||
|
|||||||
@@ -3,12 +3,14 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'package:flutter/rendering.dart';
|
|
||||||
import 'components.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
|
||||||
import '../model/puzzle_model.dart';
|
import '../model/puzzle_model.dart';
|
||||||
import '../page_content/pages_flow.dart';
|
import '../page_content/pages_flow.dart';
|
||||||
|
import 'components.dart';
|
||||||
|
|
||||||
class RotatorPuzzle extends StatefulWidget {
|
class RotatorPuzzle extends StatefulWidget {
|
||||||
final PageConfig pageConfig;
|
final PageConfig pageConfig;
|
||||||
@@ -25,7 +27,7 @@ class RotatorPuzzle extends StatefulWidget {
|
|||||||
final double tileScaleModifier;
|
final double tileScaleModifier;
|
||||||
|
|
||||||
const RotatorPuzzle({
|
const RotatorPuzzle({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.pageConfig,
|
required this.pageConfig,
|
||||||
required this.numTiles,
|
required this.numTiles,
|
||||||
required this.puzzleNum,
|
required this.puzzleNum,
|
||||||
@@ -37,7 +39,7 @@ class RotatorPuzzle extends StatefulWidget {
|
|||||||
required this.tileShadedStringAnimDuration,
|
required this.tileShadedStringAnimDuration,
|
||||||
this.tileShadedStringAnimSettings = const [],
|
this.tileShadedStringAnimSettings = const [],
|
||||||
this.tileScaleModifier = 1.0,
|
this.tileScaleModifier = 1.0,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<RotatorPuzzle> createState() => RotatorPuzzleState();
|
State<RotatorPuzzle> createState() => RotatorPuzzleState();
|
||||||
@@ -258,7 +260,7 @@ class RotatorPuzzleTile extends StatefulWidget {
|
|||||||
final int col;
|
final int col;
|
||||||
|
|
||||||
RotatorPuzzleTile({
|
RotatorPuzzleTile({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.tileID,
|
required this.tileID,
|
||||||
required this.row,
|
required this.row,
|
||||||
required this.col,
|
required this.col,
|
||||||
@@ -271,7 +273,7 @@ class RotatorPuzzleTile extends StatefulWidget {
|
|||||||
required this.animationSettings,
|
required this.animationSettings,
|
||||||
required this.tileShadedStringAnimDuration,
|
required this.tileShadedStringAnimDuration,
|
||||||
required this.tileScaleModifier,
|
required this.tileScaleModifier,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final State<RotatorPuzzleTile> tileState = RotatorPuzzleTileState();
|
final State<RotatorPuzzleTile> tileState = RotatorPuzzleTileState();
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class WonkyChar extends StatefulWidget {
|
class WonkyChar extends StatefulWidget {
|
||||||
final String text;
|
final String text;
|
||||||
@@ -13,13 +14,13 @@ class WonkyChar extends StatefulWidget {
|
|||||||
final int animDurationMillis;
|
final int animDurationMillis;
|
||||||
final List<WonkyAnimSetting> animationSettings;
|
final List<WonkyAnimSetting> animationSettings;
|
||||||
const WonkyChar({
|
const WonkyChar({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.text,
|
required this.text,
|
||||||
required this.size,
|
required this.size,
|
||||||
this.baseRotation = 0,
|
this.baseRotation = 0,
|
||||||
this.animDurationMillis = 1000,
|
this.animDurationMillis = 1000,
|
||||||
this.animationSettings = const <WonkyAnimSetting>[],
|
this.animationSettings = const <WonkyAnimSetting>[],
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<WonkyChar> createState() => WonkyCharState();
|
State<WonkyChar> createState() => WonkyCharState();
|
||||||
@@ -79,20 +80,21 @@ class WonkyCharState extends State<WonkyChar>
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
List<FontVariation> fontVariations = [];
|
List<FontVariation> fontVariations = [];
|
||||||
for (int i = 0; i < _fvAxes.length; i++) {
|
for (int i = 0; i < _fvAxes.length; i++) {
|
||||||
fontVariations.add(FontVariation(_fvAxes[i], _fvAnimations[i].value));
|
fontVariations
|
||||||
|
.add(FontVariation(_fvAxes[i], _fvAnimations[i].value as double));
|
||||||
}
|
}
|
||||||
return Transform(
|
return Transform(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
transform: Matrix4.translationValues(
|
transform: Matrix4.translationValues(_offsetXAnimation.value as double,
|
||||||
_offsetXAnimation.value, _offsetYAnimation.value, 0)
|
_offsetYAnimation.value as double, 0)
|
||||||
..scale(_scaleAnimation.value)
|
..scale(_scaleAnimation.value)
|
||||||
..rotateZ(widget.baseRotation + _rotationAnimation.value),
|
..rotateZ(widget.baseRotation + (_rotationAnimation.value as double)),
|
||||||
child: IgnorePointer(
|
child: IgnorePointer(
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.text,
|
widget.text,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: _colorAnimation.value,
|
color: _colorAnimation.value as Color?,
|
||||||
fontFamily: 'Amstelvar',
|
fontFamily: 'Amstelvar',
|
||||||
fontSize: widget.size,
|
fontSize: widget.size,
|
||||||
fontVariations: fontVariations,
|
fontVariations: fontVariations,
|
||||||
@@ -114,13 +116,15 @@ class WonkyCharState extends State<WonkyChar>
|
|||||||
);
|
);
|
||||||
late Animation animation;
|
late Animation animation;
|
||||||
if (s.property == 'color') {
|
if (s.property == 'color') {
|
||||||
animation =
|
animation = ColorTween(
|
||||||
ColorTween(begin: s.fromTo.fromValue(), end: s.fromTo.toValue())
|
begin: s.fromTo.fromValue() as Color?,
|
||||||
.animate(curve);
|
end: s.fromTo.toValue() as Color?)
|
||||||
|
.animate(curve);
|
||||||
} else {
|
} else {
|
||||||
animation =
|
animation = Tween<double>(
|
||||||
Tween<double>(begin: s.fromTo.fromValue(), end: s.fromTo.toValue())
|
begin: s.fromTo.fromValue() as double,
|
||||||
.animate(curve);
|
end: s.fromTo.toValue() as double)
|
||||||
|
.animate(curve);
|
||||||
}
|
}
|
||||||
if (s.type == 'fv') {
|
if (s.type == 'fv') {
|
||||||
_fvAxes.add(s.property);
|
_fvAxes.add(s.property);
|
||||||
@@ -168,13 +172,13 @@ class WonkyCharState extends State<WonkyChar>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class WCRange {
|
abstract class WCRange<T> {
|
||||||
WCRange();
|
WCRange();
|
||||||
fromValue() {}
|
T fromValue();
|
||||||
toValue() {}
|
T toValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
class RangeColor implements WCRange {
|
class RangeColor implements WCRange<Color> {
|
||||||
Color from;
|
Color from;
|
||||||
Color to;
|
Color to;
|
||||||
RangeColor({required this.from, required this.to});
|
RangeColor({required this.from, required this.to});
|
||||||
@@ -189,7 +193,7 @@ class RangeColor implements WCRange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RangeDbl implements WCRange {
|
class RangeDbl implements WCRange<double> {
|
||||||
double from;
|
double from;
|
||||||
double to;
|
double to;
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import '../components/components.dart';
|
import '../components/components.dart';
|
||||||
import '../page_content/pages_flow.dart';
|
import '../page_content/pages_flow.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:math';
|
|
||||||
import '../styles.dart';
|
import '../styles.dart';
|
||||||
|
|
||||||
class PageAscenderDescender extends SinglePage {
|
class PageAscenderDescender extends SinglePage {
|
||||||
const PageAscenderDescender({
|
const PageAscenderDescender({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(
|
});
|
||||||
key: key,
|
|
||||||
);
|
|
||||||
@override
|
@override
|
||||||
State<SinglePage> createState() => _PageAscenderDescenderState();
|
State<SinglePage> createState() => _PageAscenderDescenderState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import '../styles.dart';
|
|||||||
|
|
||||||
class PageNarrativePost extends NarrativePage {
|
class PageNarrativePost extends NarrativePage {
|
||||||
const PageNarrativePost({
|
const PageNarrativePost({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<NarrativePage> createState() => _PageNarrativePostState();
|
State<NarrativePage> createState() => _PageNarrativePostState();
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import '../styles.dart';
|
|||||||
|
|
||||||
class PageNarrativePre extends NarrativePage {
|
class PageNarrativePre extends NarrativePage {
|
||||||
const PageNarrativePre({
|
const PageNarrativePre({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<NarrativePage> createState() => _PageNarrativePreState();
|
State<NarrativePage> createState() => _PageNarrativePreState();
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
// Copyright 2023 The Flutter team. All rights reserved.
|
// Copyright 2023 The Flutter team. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
import '../components/components.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import '../page_content/pages_flow.dart';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../components/components.dart';
|
||||||
|
import '../page_content/pages_flow.dart';
|
||||||
import '../styles.dart';
|
import '../styles.dart';
|
||||||
|
|
||||||
class PageOpticalSize extends SinglePage {
|
class PageOpticalSize extends SinglePage {
|
||||||
const PageOpticalSize({
|
const PageOpticalSize({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SinglePage> createState() => _PageOpticalSizeState();
|
State<SinglePage> createState() => _PageOpticalSizeState();
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
// Copyright 2023 The Flutter team. All rights reserved.
|
// Copyright 2023 The Flutter team. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
import '../components/components.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../components/components.dart';
|
||||||
import '../page_content/pages_flow.dart';
|
import '../page_content/pages_flow.dart';
|
||||||
import '../styles.dart';
|
import '../styles.dart';
|
||||||
|
|
||||||
class PageWeight extends SinglePage {
|
class PageWeight extends SinglePage {
|
||||||
const PageWeight({
|
const PageWeight({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SinglePage> createState() => _PageWeightState();
|
State<SinglePage> createState() => _PageWeightState();
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
// Copyright 2023 The Flutter team. All rights reserved.
|
// Copyright 2023 The Flutter team. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
import '../components/components.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../components/components.dart';
|
||||||
import '../page_content/pages_flow.dart';
|
import '../page_content/pages_flow.dart';
|
||||||
import '../styles.dart';
|
import '../styles.dart';
|
||||||
|
|
||||||
class PageWidth extends SinglePage {
|
class PageWidth extends SinglePage {
|
||||||
const PageWidth({
|
const PageWidth({
|
||||||
Key? key,
|
super.key,
|
||||||
required super.pageConfig,
|
required super.pageConfig,
|
||||||
}) : super(
|
});
|
||||||
key: key,
|
|
||||||
);
|
|
||||||
@override
|
@override
|
||||||
State<SinglePage> createState() => _PageWidthState();
|
State<SinglePage> createState() => _PageWidthState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// Copyright 2023 The Flutter team. All rights reserved.
|
// Copyright 2023 The Flutter team. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
export 'page_ascender_descender.dart';
|
||||||
|
export 'page_narrative_post.dart';
|
||||||
|
export 'page_narrative_pre.dart';
|
||||||
|
export 'page_optical_size.dart';
|
||||||
export 'page_weight.dart';
|
export 'page_weight.dart';
|
||||||
export 'page_width.dart';
|
export 'page_width.dart';
|
||||||
export 'page_ascender_descender.dart';
|
|
||||||
export 'page_optical_size.dart';
|
|
||||||
export 'page_narrative_pre.dart';
|
|
||||||
export 'page_narrative_post.dart';
|
|
||||||
|
|||||||
@@ -2,13 +2,15 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../page_content/wallpapers_flow.dart';
|
|
||||||
import '../components/components.dart';
|
import '../components/components.dart';
|
||||||
|
import '../page_content/wallpapers_flow.dart';
|
||||||
import 'pages.dart';
|
import 'pages.dart';
|
||||||
|
|
||||||
class PagesFlow extends StatefulWidget {
|
class PagesFlow extends StatefulWidget {
|
||||||
const PagesFlow({Key? key}) : super(key: key);
|
const PagesFlow({super.key});
|
||||||
|
|
||||||
static const pageScrollDuration = 400;
|
static const pageScrollDuration = 400;
|
||||||
|
|
||||||
@@ -92,9 +94,9 @@ class PageConfig {
|
|||||||
class SinglePage extends StatefulWidget {
|
class SinglePage extends StatefulWidget {
|
||||||
final PageConfig pageConfig;
|
final PageConfig pageConfig;
|
||||||
const SinglePage({
|
const SinglePage({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.pageConfig,
|
required this.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<SinglePage> createState() => SinglePageState();
|
State<SinglePage> createState() => SinglePageState();
|
||||||
@@ -133,9 +135,9 @@ class SinglePageState extends State<SinglePage> with TickerProviderStateMixin {
|
|||||||
class NarrativePage extends StatefulWidget {
|
class NarrativePage extends StatefulWidget {
|
||||||
final PageConfig pageConfig;
|
final PageConfig pageConfig;
|
||||||
const NarrativePage({
|
const NarrativePage({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.pageConfig,
|
required this.pageConfig,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<NarrativePage> createState() => NarrativePageState();
|
State<NarrativePage> createState() => NarrativePageState();
|
||||||
|
|||||||
@@ -30,18 +30,15 @@ class TextStyles {
|
|||||||
class ButtonStyles {
|
class ButtonStyles {
|
||||||
static ButtonStyle style() {
|
static ButtonStyle style() {
|
||||||
return ButtonStyle(
|
return ButtonStyle(
|
||||||
fixedSize:
|
fixedSize: MaterialStateProperty.resolveWith<Size>((states) {
|
||||||
MaterialStateProperty.resolveWith<Size>((Set<MaterialState> states) {
|
|
||||||
return const Size(100, 36);
|
return const Size(100, 36);
|
||||||
}),
|
}),
|
||||||
shape: MaterialStateProperty.resolveWith<OutlinedBorder>(
|
shape: MaterialStateProperty.resolveWith<OutlinedBorder>((states) {
|
||||||
(Set<MaterialState> states) {
|
|
||||||
return const RoundedRectangleBorder(
|
return const RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(18)));
|
borderRadius: BorderRadius.all(Radius.circular(18)));
|
||||||
}),
|
}),
|
||||||
overlayColor: null,
|
overlayColor: null,
|
||||||
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
|
backgroundColor: MaterialStateProperty.resolveWith<Color?>((states) {
|
||||||
(Set<MaterialState> states) {
|
|
||||||
if (states.contains(MaterialState.hovered)) {
|
if (states.contains(MaterialState.hovered)) {
|
||||||
return Colors.black; // Hovered bg (for desktop with mouse)
|
return Colors.black; // Hovered bg (for desktop with mouse)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user