mirror of
https://github.com/rainloreley/shlink-manager.git
synced 2025-04-19 06:29:38 +02:00
generate tag color based on text
This commit is contained in:
parent
086ca47fc0
commit
d00ba4b4e9
@ -26,6 +26,7 @@ linter:
|
|||||||
- curly_braces_in_flow_control_structures
|
- curly_braces_in_flow_control_structures
|
||||||
# doc comments
|
# doc comments
|
||||||
- slash_for_doc_comments
|
- slash_for_doc_comments
|
||||||
|
- package_api_docs
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
# included above or to enable additional rules. A list of all available lints
|
# included above or to enable additional rules. A list of all available lints
|
||||||
|
@ -23,7 +23,7 @@ class ShortURL {
|
|||||||
VisitsSummary visitsSummary;
|
VisitsSummary visitsSummary;
|
||||||
|
|
||||||
/// List of tags assigned to this short URL
|
/// List of tags assigned to this short URL
|
||||||
List<dynamic> tags;
|
List<String> tags;
|
||||||
|
|
||||||
/// Metadata
|
/// Metadata
|
||||||
ShortURLMeta meta;
|
ShortURLMeta meta;
|
||||||
@ -58,7 +58,7 @@ class ShortURL {
|
|||||||
deviceLongUrls = DeviceLongUrls.fromJson(json["deviceLongUrls"]),
|
deviceLongUrls = DeviceLongUrls.fromJson(json["deviceLongUrls"]),
|
||||||
dateCreated = DateTime.parse(json["dateCreated"]),
|
dateCreated = DateTime.parse(json["dateCreated"]),
|
||||||
visitsSummary = VisitsSummary.fromJson(json["visitsSummary"]),
|
visitsSummary = VisitsSummary.fromJson(json["visitsSummary"]),
|
||||||
tags = json["tags"],
|
tags = (json["tags"] as List<dynamic>).map((e) => e.toString()).toList(),
|
||||||
meta = ShortURLMeta.fromJson(json["meta"]),
|
meta = ShortURLMeta.fromJson(json["meta"]),
|
||||||
domain = json["domain"],
|
domain = json["domain"],
|
||||||
title = json["title"],
|
title = json["title"],
|
||||||
|
@ -32,7 +32,8 @@ class ServerManager {
|
|||||||
return apiVersion;
|
return apiVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether the user provided information about the server (url and apikey)
|
/// Checks whether the user provided information about the server
|
||||||
|
/// (url and apikey)
|
||||||
Future<bool> checkLogin() async {
|
Future<bool> checkLogin() async {
|
||||||
await _loadCredentials();
|
await _loadCredentials();
|
||||||
return (serverUrl != null);
|
return (serverUrl != null);
|
||||||
|
19
lib/util/string_to_color.dart
Normal file
19
lib/util/string_to_color.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
Color stringToColor(String string) {
|
||||||
|
int hash = 0;
|
||||||
|
string.split('').forEach((char) {
|
||||||
|
hash = char.codeUnitAt(0) + ((hash << 5) - hash);
|
||||||
|
});
|
||||||
|
var rgb = [];
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
var value = (hash >> (i * 8)) & 0xff;
|
||||||
|
rgb.add(int.parse(value.toRadixString(16).padLeft(2, '0'), radix: 16));
|
||||||
|
}
|
||||||
|
if (rgb.length != 3) {
|
||||||
|
return const Color(0xff000000);
|
||||||
|
}
|
||||||
|
return Color.fromARGB(1, rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
import 'package:dynamic_color/dynamic_color.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:shlink_app/API/Classes/ShortURL/short_url.dart';
|
import 'package:shlink_app/API/Classes/ShortURL/short_url.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:shlink_app/API/server_manager.dart';
|
import 'package:shlink_app/API/server_manager.dart';
|
||||||
|
import 'package:shlink_app/widgets/url_tags_list_widget.dart';
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
|
|
||||||
class URLDetailView extends StatefulWidget {
|
class URLDetailView extends StatefulWidget {
|
||||||
@ -100,30 +100,7 @@ class _URLDetailViewState extends State<URLDetailView> {
|
|||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||||
child: Wrap(
|
child: UrlTagsListWidget(tags: widget.shortURL.tags)
|
||||||
children: widget.shortURL.tags.map((tag) {
|
|
||||||
var randomColor = ([...Colors.primaries]..shuffle())
|
|
||||||
.first
|
|
||||||
.harmonizeWith(Theme.of(context).colorScheme.primary);
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4, top: 4),
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 4, bottom: 4, left: 12, right: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
color: randomColor,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
tag,
|
|
||||||
style: TextStyle(
|
|
||||||
color: randomColor.computeLuminance() < 0.5
|
|
||||||
? Colors.white
|
|
||||||
: Colors.black),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList()),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_ListCell(title: "Short Code", content: widget.shortURL.shortCode),
|
_ListCell(title: "Short Code", content: widget.shortURL.shortCode),
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import 'package:dynamic_color/dynamic_color.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:qr_flutter/qr_flutter.dart';
|
import 'package:qr_flutter/qr_flutter.dart';
|
||||||
import 'package:shlink_app/API/Classes/ShortURL/short_url.dart';
|
import 'package:shlink_app/API/Classes/ShortURL/short_url.dart';
|
||||||
import 'package:shlink_app/API/server_manager.dart';
|
import 'package:shlink_app/API/server_manager.dart';
|
||||||
import 'package:shlink_app/views/short_url_edit_view.dart';
|
import 'package:shlink_app/views/short_url_edit_view.dart';
|
||||||
import 'package:shlink_app/views/url_detail_view.dart';
|
import 'package:shlink_app/views/url_detail_view.dart';
|
||||||
|
import 'package:shlink_app/widgets/url_tags_list_widget.dart';
|
||||||
import '../globals.dart' as globals;
|
import '../globals.dart' as globals;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
@ -235,31 +235,7 @@ class _ShortURLCellState extends State<ShortURLCell> {
|
|||||||
style: TextStyle(color: Colors.grey[600]),
|
style: TextStyle(color: Colors.grey[600]),
|
||||||
),
|
),
|
||||||
// List tags in a row
|
// List tags in a row
|
||||||
Wrap(
|
UrlTagsListWidget(tags: widget.shortURL.tags)
|
||||||
children: widget.shortURL.tags.map((tag) {
|
|
||||||
var randomColor = ([...Colors.primaries]..shuffle())
|
|
||||||
.first
|
|
||||||
.harmonizeWith(
|
|
||||||
Theme.of(context).colorScheme.primary);
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4, top: 4),
|
|
||||||
child: Container(
|
|
||||||
padding: const EdgeInsets.only(
|
|
||||||
top: 4, bottom: 4, left: 12, right: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(4),
|
|
||||||
color: randomColor,
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
tag,
|
|
||||||
style: TextStyle(
|
|
||||||
color: randomColor.computeLuminance() < 0.5
|
|
||||||
? Colors.white
|
|
||||||
: Colors.black),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList())
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
42
lib/widgets/url_tags_list_widget.dart
Normal file
42
lib/widgets/url_tags_list_widget.dart
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import 'package:dynamic_color/dynamic_color.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shlink_app/util/string_to_color.dart';
|
||||||
|
|
||||||
|
class UrlTagsListWidget extends StatefulWidget {
|
||||||
|
const UrlTagsListWidget({super.key, required this.tags});
|
||||||
|
|
||||||
|
final List<String> tags;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<UrlTagsListWidget> createState() => _UrlTagsListWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _UrlTagsListWidgetState extends State<UrlTagsListWidget> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Wrap(
|
||||||
|
children: widget.tags.map((tag) {
|
||||||
|
var boxColor = stringToColor(tag)
|
||||||
|
.harmonizeWith(
|
||||||
|
Theme.of(context).colorScheme.primary);
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 4, top: 4),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.only(
|
||||||
|
top: 4, bottom: 4, left: 12, right: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
color: boxColor,
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
tag,
|
||||||
|
style: TextStyle(
|
||||||
|
color: boxColor.computeLuminance() < 0.5
|
||||||
|
? Colors.white
|
||||||
|
: Colors.black),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user