💄 Adjusted developer hub
This commit is contained in:
@@ -1309,5 +1309,6 @@
|
|||||||
"presenceTypeGaming": "Playing",
|
"presenceTypeGaming": "Playing",
|
||||||
"presenceTypeMusic": "Listening to Music",
|
"presenceTypeMusic": "Listening to Music",
|
||||||
"presenceTypeWorkout": "Working out",
|
"presenceTypeWorkout": "Working out",
|
||||||
"articleCompose": "Compose Article"
|
"articleCompose": "Compose Article",
|
||||||
|
"backToHub": "Back to Hub"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,11 +158,11 @@
|
|||||||
"checkIn": "签到",
|
"checkIn": "签到",
|
||||||
"checkInNone": "尚未签到",
|
"checkInNone": "尚未签到",
|
||||||
"checkInNoneHint": "通过签到获取您的财富提示和每日奖励。",
|
"checkInNoneHint": "通过签到获取您的财富提示和每日奖励。",
|
||||||
"checkInResultLevel0": "最差运气",
|
"checkInResultLevel0": "大凶",
|
||||||
"checkInResultLevel1": "坏运气",
|
"checkInResultLevel1": "凶",
|
||||||
"checkInResultLevel2": "一个普通的日常",
|
"checkInResultLevel2": "中平",
|
||||||
"checkInResultLevel3": "好运",
|
"checkInResultLevel3": "吉",
|
||||||
"checkInResultLevel4": "最佳运气",
|
"checkInResultLevel4": "大吉",
|
||||||
"checkInActivityTitle": "{} 在 {} 签到并获得了 {}",
|
"checkInActivityTitle": "{} 在 {} 签到并获得了 {}",
|
||||||
"eventCalander": "活动日历",
|
"eventCalander": "活动日历",
|
||||||
"eventCalanderEmpty": "该日无活动。",
|
"eventCalanderEmpty": "该日无活动。",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@@ -7,6 +8,7 @@ import 'package:island/models/custom_app.dart';
|
|||||||
import 'package:island/pods/network.dart';
|
import 'package:island/pods/network.dart';
|
||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
import 'package:island/widgets/response.dart';
|
import 'package:island/widgets/response.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
@@ -83,18 +85,38 @@ class CustomAppsScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return RefreshIndicator(
|
return ExtendedRefreshIndicator(
|
||||||
onRefresh:
|
onRefresh:
|
||||||
() => ref.refresh(
|
() => ref.refresh(
|
||||||
customAppsProvider(publisherName, projectId).future,
|
customAppsProvider(publisherName, projectId).future,
|
||||||
),
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Gap(8),
|
||||||
|
Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text('customApps').tr().padding(horizontal: 8),
|
||||||
|
trailing: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.pushNamed(
|
||||||
|
'developerAppNew',
|
||||||
|
pathParameters: {
|
||||||
|
'name': publisherName,
|
||||||
|
'projectId': projectId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Symbols.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: EdgeInsets.only(top: 4),
|
padding: EdgeInsets.zero,
|
||||||
itemCount: data.length,
|
itemCount: data.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final app = data[index];
|
final app = data[index];
|
||||||
return Card(
|
return Card(
|
||||||
margin: const EdgeInsets.all(8.0),
|
|
||||||
clipBehavior: Clip.antiAlias,
|
clipBehavior: Clip.antiAlias,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -138,7 +160,10 @@ class CustomAppsScreen extends HookConsumerWidget {
|
|||||||
app.slug,
|
app.slug,
|
||||||
style: GoogleFonts.robotoMono(fontSize: 12),
|
style: GoogleFonts.robotoMono(fontSize: 12),
|
||||||
),
|
),
|
||||||
contentPadding: EdgeInsets.only(left: 20, right: 12),
|
contentPadding: EdgeInsets.only(
|
||||||
|
left: 20,
|
||||||
|
right: 12,
|
||||||
|
),
|
||||||
trailing: PopupMenuButton(
|
trailing: PopupMenuButton(
|
||||||
itemBuilder:
|
itemBuilder:
|
||||||
(context) => [
|
(context) => [
|
||||||
@@ -163,7 +188,9 @@ class CustomAppsScreen extends HookConsumerWidget {
|
|||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(
|
Text(
|
||||||
'delete',
|
'delete',
|
||||||
style: TextStyle(color: Colors.red),
|
style: TextStyle(
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
).tr(),
|
).tr(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -185,7 +212,9 @@ class CustomAppsScreen extends HookConsumerWidget {
|
|||||||
'deleteCustomApp'.tr(),
|
'deleteCustomApp'.tr(),
|
||||||
).then((confirm) {
|
).then((confirm) {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(
|
||||||
|
apiClientProvider,
|
||||||
|
);
|
||||||
client.delete(
|
client.delete(
|
||||||
'/develop/developers/$publisherName/projects/$projectId/apps/${app.id}',
|
'/develop/developers/$publisherName/projects/$projectId/apps/${app.id}',
|
||||||
);
|
);
|
||||||
@@ -207,6 +236,9 @@ class CustomAppsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/bot.dart';
|
import 'package:island/models/bot.dart';
|
||||||
@@ -10,6 +11,7 @@ import 'package:island/widgets/response.dart';
|
|||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:island/widgets/extended_refresh_indicator.dart';
|
import 'package:island/widgets/extended_refresh_indicator.dart';
|
||||||
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
|
||||||
part 'bots.g.dart';
|
part 'bots.g.dart';
|
||||||
|
|
||||||
@@ -64,8 +66,29 @@ class BotsScreen extends HookConsumerWidget {
|
|||||||
return ExtendedRefreshIndicator(
|
return ExtendedRefreshIndicator(
|
||||||
onRefresh:
|
onRefresh:
|
||||||
() => ref.refresh(botsProvider(publisherName, projectId).future),
|
() => ref.refresh(botsProvider(publisherName, projectId).future),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
const Gap(8),
|
||||||
|
Card(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text('bots').tr().padding(horizontal: 8),
|
||||||
|
trailing: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
context.pushNamed(
|
||||||
|
'developerBotNew',
|
||||||
|
pathParameters: {
|
||||||
|
'name': publisherName,
|
||||||
|
'projectId': projectId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
icon: const Icon(Symbols.add),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: EdgeInsets.zero,
|
||||||
itemCount: data.length,
|
itemCount: data.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final bot = data[index];
|
final bot = data[index];
|
||||||
@@ -102,7 +125,10 @@ class BotsScreen extends HookConsumerWidget {
|
|||||||
value: 'delete',
|
value: 'delete',
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
const Icon(Symbols.delete, color: Colors.red),
|
const Icon(
|
||||||
|
Symbols.delete,
|
||||||
|
color: Colors.red,
|
||||||
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
Text(
|
Text(
|
||||||
'delete',
|
'delete',
|
||||||
@@ -154,6 +180,9 @@ class BotsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
loading: () => const Center(child: CircularProgressIndicator()),
|
loading: () => const Center(child: CircularProgressIndicator()),
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -99,15 +97,6 @@ class DeveloperHubScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
if (currentProject.value == null)
|
|
||||||
...([
|
|
||||||
// Welcome Section
|
|
||||||
_WelcomeSection(currentDeveloper: currentDeveloper.value),
|
|
||||||
|
|
||||||
// Navigation Tabs
|
|
||||||
_NavigationTabs(),
|
|
||||||
]),
|
|
||||||
|
|
||||||
// Main Content
|
// Main Content
|
||||||
if (currentProject.value != null)
|
if (currentProject.value != null)
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -195,162 +184,6 @@ class _ConsoleAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Welcome Section
|
|
||||||
class _WelcomeSection extends StatelessWidget {
|
|
||||||
final SnDeveloper? currentDeveloper;
|
|
||||||
|
|
||||||
const _WelcomeSection({required this.currentDeveloper});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final isDark = Theme.of(context).brightness == Brightness.dark;
|
|
||||||
return Stack(
|
|
||||||
children: [
|
|
||||||
Positioned.fill(
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
gradient: LinearGradient(
|
|
||||||
colors:
|
|
||||||
isDark
|
|
||||||
? [
|
|
||||||
Theme.of(context).colorScheme.surfaceContainerHighest,
|
|
||||||
Theme.of(context).colorScheme.surfaceContainerLow,
|
|
||||||
]
|
|
||||||
: [const Color(0xFFE8F0FE), const Color(0xFFF1F3F4)],
|
|
||||||
begin: Alignment.topLeft,
|
|
||||||
end: Alignment.bottomRight,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
right: 16,
|
|
||||||
top: 0,
|
|
||||||
bottom: 0,
|
|
||||||
child: _RandomStickerImage(
|
|
||||||
width: 180,
|
|
||||||
height: 180,
|
|
||||||
).opacity(isWideScreen(context) ? 1 : 0.5),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: 180,
|
|
||||||
width: double.infinity,
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'Good morning!',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 32,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
color: Theme.of(context).colorScheme.onSurface,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
Text(
|
|
||||||
currentDeveloper != null
|
|
||||||
? "You're working as ${currentDeveloper!.publisher!.nick}"
|
|
||||||
: "Choose a developer and continue.",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Random Sticker Image Widget
|
|
||||||
class _RandomStickerImage extends StatelessWidget {
|
|
||||||
final double? width;
|
|
||||||
final double? height;
|
|
||||||
|
|
||||||
const _RandomStickerImage({this.width, this.height});
|
|
||||||
|
|
||||||
static const List<String> _stickers = [
|
|
||||||
'assets/images/stickers/clap.png',
|
|
||||||
'assets/images/stickers/confuse.png',
|
|
||||||
'assets/images/stickers/pray.png',
|
|
||||||
'assets/images/stickers/thumb_up.png',
|
|
||||||
];
|
|
||||||
|
|
||||||
String _getRandomSticker() {
|
|
||||||
final random = Random();
|
|
||||||
return _stickers[random.nextInt(_stickers.length)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Image.asset(
|
|
||||||
_getRandomSticker(),
|
|
||||||
width: width ?? 80,
|
|
||||||
height: height ?? 80,
|
|
||||||
fit: BoxFit.contain,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Navigation Tabs
|
|
||||||
class _NavigationTabs extends StatelessWidget {
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
const Gap(24),
|
|
||||||
_NavTabItem(title: 'Dashboard', isActive: true),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _NavTabItem extends StatelessWidget {
|
|
||||||
final String title;
|
|
||||||
final bool isActive;
|
|
||||||
|
|
||||||
const _NavTabItem({required this.title, this.isActive = false});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(
|
|
||||||
color:
|
|
||||||
isActive
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Colors.transparent,
|
|
||||||
width: 2,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: TextStyle(
|
|
||||||
color:
|
|
||||||
isActive
|
|
||||||
? Theme.of(context).colorScheme.primary
|
|
||||||
: Theme.of(context).colorScheme.onSurface,
|
|
||||||
fontWeight: isActive ? FontWeight.w500 : FontWeight.w400,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main Content Section
|
// Main Content Section
|
||||||
class _MainContentSection extends HookConsumerWidget {
|
class _MainContentSection extends HookConsumerWidget {
|
||||||
final SnDeveloper? currentDeveloper;
|
final SnDeveloper? currentDeveloper;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/dev_project.dart';
|
import 'package:island/models/dev_project.dart';
|
||||||
import 'package:island/screens/developers/apps.dart';
|
import 'package:island/screens/developers/apps.dart';
|
||||||
@@ -54,6 +55,36 @@ class ProjectDetailView extends HookConsumerWidget {
|
|||||||
label: Text('bots'.tr()),
|
label: Text('bots'.tr()),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
leading: Container(
|
||||||
|
width: 256,
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
bottom: 8,
|
||||||
|
top: 2,
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.onSurface.withOpacity(0.12),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
spacing: 8,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: onBackToHub,
|
||||||
|
icon: const Icon(Icons.arrow_back),
|
||||||
|
iconSize: 16,
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
|
),
|
||||||
|
Expanded(child: Text("backToHub").tr()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -69,6 +100,7 @@ class ProjectDetailView extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const Gap(4),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -737,7 +737,7 @@ class ActivityListNotifier extends _$ActivityListNotifier
|
|||||||
};
|
};
|
||||||
|
|
||||||
final response = await client.get(
|
final response = await client.get(
|
||||||
'/sphere/activities',
|
'/sphere/timeline',
|
||||||
queryParameters: queryParameters,
|
queryParameters: queryParameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user