Compare commits
89 Commits
3261db8fee
...
65e43dc633
Author | SHA1 | Date |
---|---|---|
Rongjian Zhang | 65e43dc633 | |
Rongjian Zhang | 06a96a14be | |
Rongjian Zhang | e2de7feec2 | |
Rongjian Zhang | 56402d789c | |
Rongjian Zhang | 29242aa45d | |
Rongjian Zhang | ad44495236 | |
Rongjian Zhang | 3d21b6c226 | |
Rongjian Zhang | fbb524a7de | |
Rongjian Zhang | 7bd412eb2b | |
Rongjian Zhang | 7ca3fe03c5 | |
Rongjian Zhang | b65ce98077 | |
Rongjian Zhang | fddf67d518 | |
Rongjian Zhang | 5a5b20eb7e | |
Rongjian Zhang | efd74ccd86 | |
Rongjian Zhang | 7b51747576 | |
Rongjian Zhang | 61d5a3e846 | |
Rongjian Zhang | 9892d87f9b | |
Rongjian Zhang | 826664e3f1 | |
Rongjian Zhang | e6298b2363 | |
Rongjian Zhang | 3953544d55 | |
Rongjian Zhang | f7eb0e6f62 | |
Rongjian Zhang | 830441ba05 | |
Rongjian Zhang | d86229e367 | |
Rongjian Zhang | a1182ed6a5 | |
Rongjian Zhang | 633b58d36f | |
Rongjian Zhang | 4c2a7177eb | |
Rongjian Zhang | 057bad71fe | |
Rongjian Zhang | 9b339c6cdf | |
Rongjian Zhang | 7a71d13f7d | |
Rongjian Zhang | 36e505d511 | |
Rongjian Zhang | 775b2cef49 | |
Rongjian Zhang | e872b4753d | |
Rongjian Zhang | df946c514a | |
Rongjian Zhang | e45b8fa134 | |
Rongjian Zhang | 2d28eb7b41 | |
Rongjian Zhang | 55f3f6a713 | |
Rongjian Zhang | 0a28311797 | |
Rongjian Zhang | b7dcf933a3 | |
Rongjian Zhang | 26b78a31a6 | |
Rongjian Zhang | 0e952a6ef7 | |
Rongjian Zhang | 9e2850558d | |
Rongjian Zhang | 206cd1244c | |
Rongjian Zhang | 4fe46b274a | |
Rongjian Zhang | 048d35112b | |
Rongjian Zhang | 3474d931ac | |
Rongjian Zhang | 706d456c46 | |
Rongjian Zhang | efc2359f27 | |
Rongjian Zhang | ba34337b07 | |
Rongjian Zhang | 89966a95e6 | |
Rongjian Zhang | 9df896a0db | |
Rongjian Zhang | 7b08f4cc07 | |
Rongjian Zhang | d5f3bd9f24 | |
Rongjian Zhang | a30385a414 | |
Rongjian Zhang | 8d1e3fa596 | |
Rongjian Zhang | d7972c4084 | |
Rongjian Zhang | 6df89e771e | |
Rongjian Zhang | 536b031655 | |
Rongjian Zhang | 15a57899fd | |
Rongjian Zhang | fee559ba9a | |
Rongjian Zhang | 073af6f492 | |
Rongjian Zhang | d8f38d34aa | |
Rongjian Zhang | 9b914ff1f1 | |
Rongjian Zhang | 20b7addf51 | |
Rongjian Zhang | 5214a404b1 | |
Rongjian Zhang | cf6871ce20 | |
Rongjian Zhang | 988cdbfe45 | |
Rongjian Zhang | e8eb860222 | |
Rongjian Zhang | 7e79da77ee | |
Rongjian Zhang | 606370a85e | |
Rongjian Zhang | e5929aa1b8 | |
Rongjian Zhang | f0b52e82ab | |
Rongjian Zhang | 5b7b465b09 | |
Rongjian Zhang | 8eda3e36c8 | |
Rongjian Zhang | b2e7a97dab | |
Rongjian Zhang | 137af2df75 | |
Rongjian Zhang | ec99de2b6d | |
Rongjian Zhang | 66e14509de | |
Rongjian Zhang | fac17a69ef | |
Rongjian Zhang | d9c50cd0a9 | |
Rongjian Zhang | 4e715d9697 | |
Rongjian Zhang | d250f1c95c | |
Rongjian Zhang | a512e41121 | |
Rongjian Zhang | 9545b26310 | |
Rongjian Zhang | 4af23c160d | |
Rongjian Zhang | 084bc3c86a | |
Rongjian Zhang | aac5fb866b | |
Rongjian Zhang | 08f70164f4 | |
Rongjian Zhang | cac6385e6e | |
Rongjian Zhang | 9207d52cf3 |
|
@ -45,7 +45,3 @@ app.*.map.json
|
|||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
*.gql.dart
|
||||
*.g.dart
|
||||
schema.graphql
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "all",
|
||||
"dependsOn": ["json", "github", "gitlab"]
|
||||
},
|
||||
{
|
||||
"label": "json",
|
||||
"type": "dart",
|
||||
"command": "dart",
|
||||
"args": ["run", "build_runner", "watch"]
|
||||
},
|
||||
{
|
||||
"label": "github",
|
||||
"type": "dart",
|
||||
"command": "dart",
|
||||
"cwd": "packages/gql_github",
|
||||
"args": ["run", "build_runner", "watch"]
|
||||
},
|
||||
{
|
||||
"label": "gitlab",
|
||||
"type": "dart",
|
||||
"command": "dart",
|
||||
"cwd": "packages/gql_gitlab",
|
||||
"args": ["run", "build_runner", "watch"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -22,10 +22,22 @@ linter:
|
|||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
prefer_single_quotes: true
|
||||
always_use_package_imports: true
|
||||
sort_constructors_first: true
|
||||
sort_unnamed_constructors_first: true
|
||||
avoid_types_on_closure_parameters: true
|
||||
omit_local_variable_types: true
|
||||
prefer_final_in_for_each: true
|
||||
prefer_final_locals: true
|
||||
use_super_parameters: true
|
||||
use_key_in_widget_constructors: false # waiting for auto fix: https://github.com/dart-lang/sdk/issues/50056
|
||||
avoid_print: false # TODO:
|
||||
|
||||
analyzer:
|
||||
errors:
|
||||
todo: ignore
|
||||
fixme: ignore
|
||||
exclude:
|
||||
- "**/*.gql.dart"
|
||||
- "**/*.g.dart"
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2,17 +2,19 @@ PODS:
|
|||
- Flutter (1.0.0)
|
||||
- launch_review (0.0.1):
|
||||
- Flutter
|
||||
- maps_launcher (0.0.1):
|
||||
- Flutter
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- path_provider_ios (0.0.1):
|
||||
- Flutter
|
||||
- Sentry (7.23.0):
|
||||
- Sentry/Core (= 7.23.0)
|
||||
- Sentry/Core (7.23.0)
|
||||
- Sentry (7.26.0):
|
||||
- Sentry/Core (= 7.26.0)
|
||||
- Sentry/Core (7.26.0)
|
||||
- sentry_flutter (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- Sentry (~> 7.23.0)
|
||||
- Sentry (~> 7.26.0)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- shared_preferences_ios (0.0.1):
|
||||
|
@ -27,6 +29,7 @@ PODS:
|
|||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- launch_review (from `.symlinks/plugins/launch_review/ios`)
|
||||
- maps_launcher (from `.symlinks/plugins/maps_launcher/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||
- sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`)
|
||||
|
@ -45,6 +48,8 @@ EXTERNAL SOURCES:
|
|||
:path: Flutter
|
||||
launch_review:
|
||||
:path: ".symlinks/plugins/launch_review/ios"
|
||||
maps_launcher:
|
||||
:path: ".symlinks/plugins/maps_launcher/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
path_provider_ios:
|
||||
|
@ -65,10 +70,11 @@ EXTERNAL SOURCES:
|
|||
SPEC CHECKSUMS:
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
launch_review: 75d5a956ba8eaa493e9c9d4bf4c05e505e8d5ed0
|
||||
maps_launcher: 2e5b6a2d664ec6c27f82ffa81b74228d770ab203
|
||||
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
|
||||
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
|
||||
Sentry: a0d4563fa4ddacba31fdcc35daaa8573d87224d6
|
||||
sentry_flutter: 8bde7d0e57a721727fe573f13bb292c497b5a249
|
||||
Sentry: 6b8f4a4f93c2471b0d73819c52da0c0ce4f0323c
|
||||
sentry_flutter: 6604b70e74bfb15522c23788295e1debdbc86676
|
||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
||||
uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
|
||||
|
|
119
lib/app.dart
119
lib/app.dart
|
@ -1,5 +1,5 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
|
@ -8,77 +8,70 @@ import 'package:intl/locale.dart' as l;
|
|||
import 'package:provider/provider.dart';
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
// ignore: prefer_function_declarations_over_variables
|
||||
final LocaleListResolutionCallback localeListResolutionCallback =
|
||||
(locales, supportedLocales) {
|
||||
// 1. user set locale
|
||||
// 2. system locale
|
||||
try {
|
||||
if (theme.locale != null) {
|
||||
final intlLocale = l.Locale.parse(theme.locale!);
|
||||
locales = [
|
||||
Locale.fromSubtags(
|
||||
languageCode: intlLocale.languageCode,
|
||||
countryCode: intlLocale.countryCode,
|
||||
scriptCode: intlLocale.scriptCode,
|
||||
),
|
||||
...locales!
|
||||
];
|
||||
}
|
||||
} catch (err) {
|
||||
print(err);
|
||||
}
|
||||
|
||||
for (final locale in locales!) {
|
||||
// this is necessary because Flutter only handles zh_Hans -> zh
|
||||
// and would not handle non-exist language code
|
||||
if (AppLocalizations.delegate.isSupported(locale)) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. if none match, use the default
|
||||
return supportedLocales.firstWhere((l) => l.languageCode == 'en');
|
||||
};
|
||||
|
||||
return Container(
|
||||
return AntTheme(
|
||||
key: auth.rootKey,
|
||||
child: theme.theme == AppThemeType.cupertino
|
||||
? CupertinoApp.router(
|
||||
routeInformationProvider: router.routeInformationProvider,
|
||||
routeInformationParser: router.routeInformationParser,
|
||||
routerDelegate: router.routerDelegate,
|
||||
theme: CupertinoThemeData(brightness: theme.brightness),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localeListResolutionCallback: localeListResolutionCallback,
|
||||
)
|
||||
: MaterialApp.router(
|
||||
routeInformationProvider: router.routeInformationProvider,
|
||||
routeInformationParser: router.routeInformationParser,
|
||||
routerDelegate: router.routerDelegate,
|
||||
theme: ThemeData(
|
||||
brightness: theme.brightness,
|
||||
primaryColor:
|
||||
theme.brightness == Brightness.dark ? null : Colors.white,
|
||||
scaffoldBackgroundColor: theme.palette.background,
|
||||
pageTransitionsTheme: const PageTransitionsTheme(
|
||||
builders: {
|
||||
TargetPlatform.android: ZoomPageTransitionsBuilder(),
|
||||
},
|
||||
data: AntThemeData(brightness: theme.brightness),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
final antTheme = AntTheme.of(context);
|
||||
|
||||
return CupertinoApp.router(
|
||||
routeInformationProvider: router.routeInformationProvider,
|
||||
routeInformationParser: router.routeInformationParser,
|
||||
routerDelegate: router.routerDelegate,
|
||||
theme: CupertinoThemeData(
|
||||
brightness: theme.brightness,
|
||||
primaryColor: antTheme.colorPrimary,
|
||||
scaffoldBackgroundColor: antTheme.colorBox,
|
||||
textTheme: CupertinoTextThemeData(
|
||||
textStyle: TextStyle(
|
||||
fontSize: antTheme.fontSizeMain,
|
||||
color: antTheme.colorText,
|
||||
),
|
||||
colorScheme: ColorScheme.fromSwatch()
|
||||
.copyWith(secondary: theme.palette.primary),
|
||||
),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localeListResolutionCallback: localeListResolutionCallback,
|
||||
),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
localeListResolutionCallback: (locales, supportedLocales) {
|
||||
// 1. user set locale
|
||||
// 2. system locale
|
||||
try {
|
||||
if (theme.locale != null) {
|
||||
final intlLocale = l.Locale.parse(theme.locale!);
|
||||
locales = [
|
||||
Locale.fromSubtags(
|
||||
languageCode: intlLocale.languageCode,
|
||||
countryCode: intlLocale.countryCode,
|
||||
scriptCode: intlLocale.scriptCode,
|
||||
),
|
||||
...locales!
|
||||
];
|
||||
}
|
||||
} catch (err) {
|
||||
print(err);
|
||||
}
|
||||
|
||||
for (final locale in locales!) {
|
||||
// this is necessary because Flutter only handles zh_Hans -> zh
|
||||
// and would not handle non-exist language code
|
||||
if (AppLocalizations.delegate.isSupported(locale)) {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. if none match, use the default
|
||||
return supportedLocales.firstWhere((l) => l.languageCode == 'en');
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
|
@ -33,7 +34,7 @@ import 'package:universal_io/io.dart';
|
|||
|
||||
class Home extends StatefulWidget {
|
||||
@override
|
||||
_HomeState createState() => _HomeState();
|
||||
State<Home> createState() => _HomeState();
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> {
|
||||
|
@ -63,7 +64,7 @@ class _HomeState extends State<Home> {
|
|||
// go to app store
|
||||
LaunchReview.launch(writeReview: false);
|
||||
} else {
|
||||
context.read<ThemeModel>().push(context, latest.htmlUrl!);
|
||||
context.pushUrl(latest.htmlUrl!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +92,7 @@ class _HomeState extends State<Home> {
|
|||
case 3:
|
||||
return GhSearchScreen();
|
||||
case 4:
|
||||
return GhViewer();
|
||||
return const GhViewerScreen();
|
||||
}
|
||||
break;
|
||||
case PlatformType.gitlab:
|
||||
|
@ -143,8 +144,7 @@ class _HomeState extends State<Home> {
|
|||
}
|
||||
|
||||
Widget _buildNotificationIcon(BuildContext context, IconData iconData) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
int count = Provider.of<NotificationModel>(context).count;
|
||||
final count = Provider.of<NotificationModel>(context).count;
|
||||
if (count == 0) {
|
||||
return Icon(iconData);
|
||||
}
|
||||
|
@ -154,10 +154,11 @@ class _HomeState extends State<Home> {
|
|||
children: <Widget>[
|
||||
Icon(iconData),
|
||||
Positioned(
|
||||
right: -2,
|
||||
top: -2,
|
||||
child: Icon(Octicons.primitive_dot,
|
||||
color: theme.palette.primary, size: 14))
|
||||
right: -2,
|
||||
top: -2,
|
||||
child: Icon(Octicons.dot_fill,
|
||||
color: AntTheme.of(context).colorPrimary, size: 14),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -238,7 +239,6 @@ class _HomeState extends State<Home> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
|
||||
if (auth.activeAccount == null) {
|
||||
|
@ -247,56 +247,35 @@ class _HomeState extends State<Home> {
|
|||
|
||||
final navigationItems = _buildNavigationItems(auth.activeAccount!.platform);
|
||||
|
||||
switch (theme.theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return !(await getNavigatorKey(auth.activeTab)
|
||||
.currentState
|
||||
?.maybePop())!;
|
||||
},
|
||||
child: CupertinoTabScaffold(
|
||||
tabBuilder: (context, index) {
|
||||
return CupertinoTabView(
|
||||
navigatorKey: getNavigatorKey(index),
|
||||
builder: (context) {
|
||||
return _buildScreen(index);
|
||||
},
|
||||
);
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return !(await getNavigatorKey(auth.activeTab)
|
||||
.currentState
|
||||
?.maybePop())!;
|
||||
},
|
||||
child: CupertinoTabScaffold(
|
||||
tabBuilder: (context, index) {
|
||||
return CupertinoTabView(
|
||||
navigatorKey: getNavigatorKey(index),
|
||||
builder: (context) {
|
||||
return _buildScreen(index);
|
||||
},
|
||||
tabBar: CupertinoTabBar(
|
||||
items: navigationItems,
|
||||
currentIndex: auth.activeTab,
|
||||
onTap: (index) {
|
||||
if (auth.activeTab == index) {
|
||||
getNavigatorKey(index)
|
||||
.currentState
|
||||
?.popUntil((route) => route.isFirst);
|
||||
} else {
|
||||
auth.setActiveTab(index);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Scaffold(
|
||||
body: IndexedStack(
|
||||
index: auth.activeTab,
|
||||
children: [
|
||||
for (var i = 0; i < navigationItems.length; i++) _buildScreen(i)
|
||||
],
|
||||
),
|
||||
bottomNavigationBar: BottomNavigationBar(
|
||||
selectedItemColor: theme.palette.primary,
|
||||
items: navigationItems,
|
||||
currentIndex: auth.activeTab,
|
||||
type: BottomNavigationBarType.fixed,
|
||||
onTap: (int index) {
|
||||
);
|
||||
},
|
||||
tabBar: CupertinoTabBar(
|
||||
items: navigationItems,
|
||||
currentIndex: auth.activeTab,
|
||||
onTap: (index) {
|
||||
if (auth.activeTab == index) {
|
||||
getNavigatorKey(index)
|
||||
.currentState
|
||||
?.popUntil((route) => route.isFirst);
|
||||
} else {
|
||||
auth.setActiveTab(index);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,18 +115,6 @@
|
|||
"@dark": {
|
||||
"description": "dark mode"
|
||||
},
|
||||
"scaffoldTheme": "Scaffold Theme",
|
||||
"@scaffoldTheme": {
|
||||
"description": "Kind of theme - cupertino or material"
|
||||
},
|
||||
"cupertino": "Cupertino",
|
||||
"@cupertino": {
|
||||
"description": "Cupertino scaffold theme"
|
||||
},
|
||||
"material": "Material",
|
||||
"@material": {
|
||||
"description": "Material scaffold theme"
|
||||
},
|
||||
"codeTheme": "Code Theme",
|
||||
"@codeTheme": {
|
||||
"description": "code theme"
|
||||
|
@ -490,7 +478,7 @@
|
|||
},
|
||||
"reviewed": "reviewed",
|
||||
"@reviewed": {
|
||||
"description": "reviewed"
|
||||
"description": "reviewed"
|
||||
},
|
||||
"mergedEventMessage": "merged commit {commit} into {mergeRefName}",
|
||||
"@mergedEventMessage": {
|
||||
|
@ -688,10 +676,10 @@
|
|||
"description": "example: repo1,repo2 were added to the installation id ID",
|
||||
"placeholders": {
|
||||
"repos": {
|
||||
"type": "String"
|
||||
"type": "String"
|
||||
},
|
||||
"id": {
|
||||
"type": "String"
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -703,7 +691,7 @@
|
|||
"type": "String"
|
||||
},
|
||||
"id": {
|
||||
"type": "String"
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -745,7 +733,7 @@
|
|||
},
|
||||
"was": "was",
|
||||
"@was": {
|
||||
"description": "was"
|
||||
"description": "was"
|
||||
},
|
||||
"convertProjectCard": "converted the project card into an issue",
|
||||
"@convertProjectCard": {
|
||||
|
@ -781,7 +769,7 @@
|
|||
},
|
||||
"made": "made",
|
||||
"@made": {
|
||||
"description": "made"
|
||||
"description": "made"
|
||||
},
|
||||
"public": "public",
|
||||
"@public": {
|
||||
|
@ -821,7 +809,7 @@
|
|||
"type": "String"
|
||||
},
|
||||
"affectedRange": {
|
||||
"type": "String"
|
||||
"type": "String"
|
||||
},
|
||||
"action": {
|
||||
"type": "String"
|
||||
|
@ -836,7 +824,7 @@
|
|||
"type": "String"
|
||||
},
|
||||
"action": {
|
||||
"type": "String"
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/app.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/code.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||
|
||||
|
@ -17,8 +15,6 @@ void main() async {
|
|||
},
|
||||
// Init your App.
|
||||
appRunner: () async {
|
||||
GoogleFonts.config.allowRuntimeFetching = false;
|
||||
|
||||
final notificationModel = NotificationModel();
|
||||
final themeModel = ThemeModel();
|
||||
final authModel = AuthModel();
|
||||
|
@ -29,11 +25,6 @@ void main() async {
|
|||
codeModel.init(),
|
||||
]);
|
||||
|
||||
// To match status bar color to app bar color
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
));
|
||||
|
||||
runApp(MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider(create: (context) => notificationModel),
|
||||
|
@ -41,7 +32,7 @@ void main() async {
|
|||
ChangeNotifierProvider(create: (context) => authModel),
|
||||
ChangeNotifierProvider(create: (context) => codeModel),
|
||||
],
|
||||
child: MyApp(),
|
||||
child: const MyApp(),
|
||||
));
|
||||
},
|
||||
);
|
||||
|
|
|
@ -4,14 +4,7 @@ part 'account.g.dart';
|
|||
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
class Account {
|
||||
String platform;
|
||||
String domain;
|
||||
String token;
|
||||
String login;
|
||||
String avatarUrl;
|
||||
int? gitlabId; // For GitLab
|
||||
String? appPassword; // For Bitbucket
|
||||
String? accountId; // For Bitbucket
|
||||
// For Bitbucket
|
||||
|
||||
// equals(Account a) {
|
||||
// final uri = Uri.parse(domain);
|
||||
|
@ -38,6 +31,14 @@ class Account {
|
|||
|
||||
factory Account.fromJson(Map<String, dynamic> json) =>
|
||||
_$AccountFromJson(json);
|
||||
String platform;
|
||||
String domain;
|
||||
String token;
|
||||
String login;
|
||||
String avatarUrl;
|
||||
int? gitlabId; // For GitLab
|
||||
String? appPassword; // For Bitbucket
|
||||
String? accountId;
|
||||
|
||||
Map<String, dynamic> toJson() => _$AccountToJson(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'account.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Account _$AccountFromJson(Map<String, dynamic> json) => Account(
|
||||
platform: json['platform'] as String,
|
||||
domain: json['domain'] as String,
|
||||
token: json['token'] as String,
|
||||
login: json['login'] as String,
|
||||
avatarUrl: json['avatarUrl'] as String,
|
||||
gitlabId: json['gitlabId'] as int?,
|
||||
appPassword: json['appPassword'] as String?,
|
||||
accountId: json['accountId'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$AccountToJson(Account instance) {
|
||||
final val = <String, dynamic>{
|
||||
'platform': instance.platform,
|
||||
'domain': instance.domain,
|
||||
'token': instance.token,
|
||||
'login': instance.login,
|
||||
'avatarUrl': instance.avatarUrl,
|
||||
};
|
||||
|
||||
void writeNotNull(String key, dynamic value) {
|
||||
if (value != null) {
|
||||
val[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
writeNotNull('gitlabId', instance.gitlabId);
|
||||
writeNotNull('appPassword', instance.appPassword);
|
||||
writeNotNull('accountId', instance.accountId);
|
||||
return val;
|
||||
}
|
|
@ -1,25 +1,26 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:ferry/ferry.dart';
|
||||
// import 'package:in_app_review/in_app_review.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
import 'package:fimber/fimber.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/account.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/models/gitea.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/gitlab.dart';
|
||||
import 'package:git_touch/models/gogs.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:gql_http_link/gql_http_link.dart';
|
||||
import 'package:fimber/fimber.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
import 'package:nanoid/nanoid.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../utils/utils.dart';
|
||||
import 'account.dart';
|
||||
import 'gitlab.dart';
|
||||
import 'gogs.dart';
|
||||
import 'package:uni_links/uni_links.dart';
|
||||
// import 'package:in_app_review/in_app_review.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
const clientId = 'df930d7d2e219f26142a';
|
||||
|
||||
|
@ -33,16 +34,16 @@ class PlatformType {
|
|||
}
|
||||
|
||||
class DataWithPage<T> {
|
||||
T data;
|
||||
int cursor;
|
||||
bool hasMore;
|
||||
int total;
|
||||
DataWithPage({
|
||||
required this.data,
|
||||
required this.cursor,
|
||||
required this.hasMore,
|
||||
required this.total,
|
||||
});
|
||||
T data;
|
||||
int cursor;
|
||||
bool hasMore;
|
||||
int total;
|
||||
}
|
||||
|
||||
class AuthModel with ChangeNotifier {
|
||||
|
@ -106,7 +107,7 @@ class AuthModel with ChangeNotifier {
|
|||
await loginWithToken(token);
|
||||
}
|
||||
|
||||
Future<void> loginWithToken(String token) async {
|
||||
Future<void> loginWithToken(String t) async {
|
||||
try {
|
||||
final queryData = await query('''
|
||||
{
|
||||
|
@ -115,12 +116,12 @@ class AuthModel with ChangeNotifier {
|
|||
avatarUrl
|
||||
}
|
||||
}
|
||||
''', token);
|
||||
''', t);
|
||||
|
||||
await _addAccount(Account(
|
||||
platform: PlatformType.github,
|
||||
domain: 'https://github.com',
|
||||
token: token,
|
||||
token: t,
|
||||
login: queryData['viewer']['login'] as String,
|
||||
avatarUrl: queryData['viewer']['avatarUrl'] as String,
|
||||
));
|
||||
|
@ -199,7 +200,7 @@ class AuthModel with ChangeNotifier {
|
|||
hasMore: next != null,
|
||||
total: int.tryParse(
|
||||
res.headers['X-Total'] ?? res.headers['x-total'] ?? '') ??
|
||||
TOTAL_COUNT_FALLBACK,
|
||||
kTotalCountFallback,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -236,7 +237,7 @@ class AuthModel with ChangeNotifier {
|
|||
Map<String, dynamic> body = const {},
|
||||
}) async {
|
||||
late http.Response res;
|
||||
Map<String, String> headers = {
|
||||
final headers = <String, String>{
|
||||
'Authorization': 'token $token',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
};
|
||||
|
@ -284,7 +285,7 @@ class AuthModel with ChangeNotifier {
|
|||
Future<DataWithPage> fetchGiteaWithPage(String path,
|
||||
{int? page, int? limit}) async {
|
||||
page = page ?? 1;
|
||||
limit = limit ?? PAGE_SIZE;
|
||||
limit = limit ?? kPageSize;
|
||||
|
||||
var uri = Uri.parse('${activeAccount!.domain}/api/v1$path');
|
||||
uri = uri.replace(
|
||||
|
@ -302,7 +303,7 @@ class AuthModel with ChangeNotifier {
|
|||
cursor: page + 1,
|
||||
hasMore: info is List && info.isNotEmpty,
|
||||
total: int.tryParse(res.headers['x-total-count'] ?? '') ??
|
||||
TOTAL_COUNT_FALLBACK,
|
||||
kTotalCountFallback,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -340,7 +341,7 @@ class AuthModel with ChangeNotifier {
|
|||
Map<String, dynamic> body = const {},
|
||||
}) async {
|
||||
late http.Response res;
|
||||
Map<String, String> headers = {
|
||||
final headers = <String, String>{
|
||||
'Authorization': 'token $token',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
};
|
||||
|
@ -388,7 +389,7 @@ class AuthModel with ChangeNotifier {
|
|||
Future<DataWithPage> fetchGogsWithPage(String path,
|
||||
{int? page, int? limit}) async {
|
||||
page = page ?? 1;
|
||||
limit = limit ?? PAGE_SIZE;
|
||||
limit = limit ?? kPageSize;
|
||||
|
||||
var uri = Uri.parse('${activeAccount!.domain}/api/v1$path');
|
||||
uri = uri.replace(
|
||||
|
@ -406,7 +407,7 @@ class AuthModel with ChangeNotifier {
|
|||
cursor: page + 1,
|
||||
hasMore: info is List && info.isNotEmpty,
|
||||
total: int.tryParse(res.headers['x-total-count'] ?? '') ??
|
||||
TOTAL_COUNT_FALLBACK,
|
||||
kTotalCountFallback,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -416,7 +417,7 @@ class AuthModel with ChangeNotifier {
|
|||
Map<String, dynamic> body = const {},
|
||||
}) async {
|
||||
http.Response res;
|
||||
Map<String, String> headers = {
|
||||
final headers = <String, String>{
|
||||
'Authorization': 'token $token',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
};
|
||||
|
@ -475,7 +476,7 @@ class AuthModel with ChangeNotifier {
|
|||
Future<DataWithPage> fetchGiteeWithPage(String path,
|
||||
{int? page, int? limit}) async {
|
||||
page = page ?? 1;
|
||||
limit = limit ?? PAGE_SIZE;
|
||||
limit = limit ?? kPageSize;
|
||||
|
||||
var uri = Uri.parse('${activeAccount!.domain}/api/v5$path');
|
||||
uri = uri.replace(
|
||||
|
@ -490,7 +491,7 @@ class AuthModel with ChangeNotifier {
|
|||
|
||||
final totalPage = int.tryParse(res.headers['total_page'] ?? '');
|
||||
final totalCount =
|
||||
int.tryParse(res.headers['total_count'] ?? '') ?? TOTAL_COUNT_FALLBACK;
|
||||
int.tryParse(res.headers['total_count'] ?? '') ?? kTotalCountFallback;
|
||||
|
||||
return DataWithPage(
|
||||
data: info,
|
||||
|
@ -541,7 +542,7 @@ class AuthModel with ChangeNotifier {
|
|||
userInfo: '${activeAccount!.login}:${activeAccount!.appPassword}',
|
||||
path: input.path,
|
||||
queryParameters: {
|
||||
'pagelen': PAGE_SIZE.toString(),
|
||||
'pagelen': kPageSize.toString(),
|
||||
...input.queryParameters
|
||||
},
|
||||
);
|
||||
|
@ -610,11 +611,11 @@ class AuthModel with ChangeNotifier {
|
|||
Fimber.e('getUriLinksStream failed', ex: err);
|
||||
});
|
||||
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// Read accounts
|
||||
try {
|
||||
String? str = prefs.getString(StorageKeys.accounts);
|
||||
final str = prefs.getString(StorageKeys.accounts);
|
||||
// Fimber.d('read accounts: $str');
|
||||
_accounts = (json.decode(str ?? '[]') as List)
|
||||
.map((item) => Account.fromJson(item))
|
||||
|
@ -663,7 +664,8 @@ class AuthModel with ChangeNotifier {
|
|||
StorageKeys.getDefaultStartTabKey(activeAccount!.platform)) ??
|
||||
0;
|
||||
_ghClient = null;
|
||||
_gqlClient = null;
|
||||
_ghGqlClient = null;
|
||||
_glGqlClient = null;
|
||||
notifyListeners();
|
||||
|
||||
// TODO: strategy
|
||||
|
@ -688,29 +690,39 @@ class AuthModel with ChangeNotifier {
|
|||
return _ghClient!;
|
||||
}
|
||||
|
||||
Client? _gqlClient;
|
||||
Client get gqlClient {
|
||||
_gqlClient ??= Client(
|
||||
Client? _ghGqlClient;
|
||||
Client get ghGqlClient {
|
||||
return _ghGqlClient ??= Client(
|
||||
link: HttpLink(
|
||||
'$_apiPrefix/graphql',
|
||||
defaultHeaders: {HttpHeaders.authorizationHeader: 'token $token'},
|
||||
),
|
||||
// https://ferrygraphql.com/docs/fetch-policies#default-fetchpolicies
|
||||
defaultFetchPolicies: {
|
||||
OperationType.query: FetchPolicy.NetworkOnly,
|
||||
},
|
||||
defaultFetchPolicies: {OperationType.query: FetchPolicy.NetworkOnly},
|
||||
);
|
||||
|
||||
return _gqlClient!;
|
||||
}
|
||||
|
||||
Future<dynamic> query(String query, [String? token]) async {
|
||||
token ??= token;
|
||||
Client? _glGqlClient;
|
||||
Client get glGqlClient {
|
||||
return _glGqlClient ??= Client(
|
||||
link: HttpLink(
|
||||
Uri.parse(activeAccount!.domain)
|
||||
.replace(path: '/api/graphql')
|
||||
.toString(),
|
||||
defaultHeaders: {'Private-Token': token},
|
||||
),
|
||||
// https://ferrygraphql.com/docs/fetch-policies#default-fetchpolicies
|
||||
defaultFetchPolicies: {OperationType.query: FetchPolicy.NetworkOnly},
|
||||
);
|
||||
}
|
||||
|
||||
Future<dynamic> query(String query, [String? t]) async {
|
||||
t ??= token;
|
||||
|
||||
final res = await http
|
||||
.post(Uri.parse('$_apiPrefix/graphql'),
|
||||
headers: {
|
||||
HttpHeaders.authorizationHeader: 'token $token',
|
||||
HttpHeaders.authorizationHeader: 'token $t',
|
||||
HttpHeaders.contentTypeHeader: 'application/json'
|
||||
},
|
||||
body: json.encode({'query': query}))
|
||||
|
|
|
@ -1,39 +1,42 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'bitbucket.g.dart';
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbPagination {
|
||||
String? next;
|
||||
List values;
|
||||
BbPagination({required this.values});
|
||||
factory BbPagination.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbPaginationFromJson(json);
|
||||
String? next;
|
||||
List values;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbRepoOwner {
|
||||
BbRepoOwner();
|
||||
factory BbRepoOwner.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbRepoOwnerFromJson(json);
|
||||
String? nickname;
|
||||
String? displayName;
|
||||
String? type; // user, team
|
||||
Map<String, dynamic>? links;
|
||||
String? get avatarUrl => links!['avatar']['href'];
|
||||
BbRepoOwner();
|
||||
factory BbRepoOwner.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbRepoOwnerFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbUser extends BbRepoOwner {
|
||||
BbUser();
|
||||
factory BbUser.fromJson(Map<String, dynamic> json) => _$BbUserFromJson(json);
|
||||
String? username;
|
||||
bool? isStaff;
|
||||
DateTime? createdOn;
|
||||
String? accountId;
|
||||
BbUser();
|
||||
factory BbUser.fromJson(Map<String, dynamic> json) => _$BbUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbRepo {
|
||||
BbRepo();
|
||||
factory BbRepo.fromJson(Map<String, dynamic> json) => _$BbRepoFromJson(json);
|
||||
String? name;
|
||||
BbRepoOwner? owner;
|
||||
String? website;
|
||||
|
@ -50,51 +53,52 @@ class BbRepo {
|
|||
Map<String, dynamic>? links;
|
||||
String get ownerLogin => fullName!.split('/')[0]; // owner has no username
|
||||
String? get avatarUrl => links!['avatar']['href'];
|
||||
BbRepo();
|
||||
factory BbRepo.fromJson(Map<String, dynamic> json) => _$BbRepoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbRepoMainbranch {
|
||||
String? type;
|
||||
String? name;
|
||||
BbRepoMainbranch();
|
||||
factory BbRepoMainbranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbRepoMainbranchFromJson(json);
|
||||
String? type;
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbTree {
|
||||
BbTree({required this.type, required this.path});
|
||||
factory BbTree.fromJson(Map<String, dynamic> json) => _$BbTreeFromJson(json);
|
||||
String type;
|
||||
String path;
|
||||
int? size;
|
||||
Map<String, dynamic>? links;
|
||||
BbTree({required this.type, required this.path});
|
||||
factory BbTree.fromJson(Map<String, dynamic> json) => _$BbTreeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbCommit {
|
||||
BbCommit();
|
||||
factory BbCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommitFromJson(json);
|
||||
String? message;
|
||||
DateTime? date;
|
||||
String? hash;
|
||||
BbCommitAuthor? author;
|
||||
BbCommit();
|
||||
factory BbCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbCommitAuthor {
|
||||
String? raw;
|
||||
BbRepoOwner? user;
|
||||
BbCommitAuthor();
|
||||
factory BbCommitAuthor.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommitAuthorFromJson(json);
|
||||
String? raw;
|
||||
BbRepoOwner? user;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbIssues {
|
||||
BbIssues();
|
||||
factory BbIssues.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbIssuesFromJson(json);
|
||||
String? priority;
|
||||
String? state;
|
||||
BbRepo? repository;
|
||||
|
@ -103,50 +107,47 @@ class BbIssues {
|
|||
DateTime? createdOn;
|
||||
Map<String, dynamic>? links;
|
||||
String? get issueLink => links!['self']['href'];
|
||||
BbIssues();
|
||||
factory BbIssues.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbIssuesFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbPulls {
|
||||
BbPulls();
|
||||
factory BbPulls.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbPullsFromJson(json);
|
||||
String? description;
|
||||
BbRepoOwner? author;
|
||||
String? title;
|
||||
Map<String, dynamic>? links;
|
||||
String? get pullRequestLink => links!['self']['href'];
|
||||
DateTime? createdOn;
|
||||
BbPulls();
|
||||
factory BbPulls.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbPullsFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbCommentContent {
|
||||
String? raw;
|
||||
String? markup;
|
||||
String? html;
|
||||
BbCommentContent();
|
||||
factory BbCommentContent.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommentContentFromJson(json);
|
||||
String? raw;
|
||||
String? markup;
|
||||
String? html;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbComment {
|
||||
BbComment();
|
||||
factory BbComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommentFromJson(json);
|
||||
String? createdOn;
|
||||
String? updatedOn;
|
||||
BbCommentContent? content;
|
||||
BbRepoOwner? user;
|
||||
BbComment();
|
||||
factory BbComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbCommentFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class BbBranch {
|
||||
String? name;
|
||||
String? type;
|
||||
BbBranch();
|
||||
factory BbBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$BbBranchFromJson(json);
|
||||
String? name;
|
||||
String? type;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,231 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'bitbucket.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
BbPagination _$BbPaginationFromJson(Map<String, dynamic> json) => BbPagination(
|
||||
values: json['values'] as List<dynamic>,
|
||||
)..next = json['next'] as String?;
|
||||
|
||||
Map<String, dynamic> _$BbPaginationToJson(BbPagination instance) =>
|
||||
<String, dynamic>{
|
||||
'next': instance.next,
|
||||
'values': instance.values,
|
||||
};
|
||||
|
||||
BbRepoOwner _$BbRepoOwnerFromJson(Map<String, dynamic> json) => BbRepoOwner()
|
||||
..nickname = json['nickname'] as String?
|
||||
..displayName = json['display_name'] as String?
|
||||
..type = json['type'] as String?
|
||||
..links = json['links'] as Map<String, dynamic>?;
|
||||
|
||||
Map<String, dynamic> _$BbRepoOwnerToJson(BbRepoOwner instance) =>
|
||||
<String, dynamic>{
|
||||
'nickname': instance.nickname,
|
||||
'display_name': instance.displayName,
|
||||
'type': instance.type,
|
||||
'links': instance.links,
|
||||
};
|
||||
|
||||
BbUser _$BbUserFromJson(Map<String, dynamic> json) => BbUser()
|
||||
..nickname = json['nickname'] as String?
|
||||
..displayName = json['display_name'] as String?
|
||||
..type = json['type'] as String?
|
||||
..links = json['links'] as Map<String, dynamic>?
|
||||
..username = json['username'] as String?
|
||||
..isStaff = json['is_staff'] as bool?
|
||||
..createdOn = json['created_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_on'] as String)
|
||||
..accountId = json['account_id'] as String?;
|
||||
|
||||
Map<String, dynamic> _$BbUserToJson(BbUser instance) => <String, dynamic>{
|
||||
'nickname': instance.nickname,
|
||||
'display_name': instance.displayName,
|
||||
'type': instance.type,
|
||||
'links': instance.links,
|
||||
'username': instance.username,
|
||||
'is_staff': instance.isStaff,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
'account_id': instance.accountId,
|
||||
};
|
||||
|
||||
BbRepo _$BbRepoFromJson(Map<String, dynamic> json) => BbRepo()
|
||||
..name = json['name'] as String?
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: BbRepoOwner.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..website = json['website'] as String?
|
||||
..language = json['language'] as String?
|
||||
..size = json['size'] as int?
|
||||
..type = json['type'] as String?
|
||||
..isPrivate = json['is_private'] as bool?
|
||||
..createdOn = json['created_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_on'] as String)
|
||||
..updatedOn = json['updated_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_on'] as String)
|
||||
..description = json['description'] as String?
|
||||
..fullName = json['full_name'] as String?
|
||||
..slug = json['slug'] as String?
|
||||
..mainbranch = json['mainbranch'] == null
|
||||
? null
|
||||
: BbRepoMainbranch.fromJson(json['mainbranch'] as Map<String, dynamic>)
|
||||
..links = json['links'] as Map<String, dynamic>?;
|
||||
|
||||
Map<String, dynamic> _$BbRepoToJson(BbRepo instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'owner': instance.owner,
|
||||
'website': instance.website,
|
||||
'language': instance.language,
|
||||
'size': instance.size,
|
||||
'type': instance.type,
|
||||
'is_private': instance.isPrivate,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
'updated_on': instance.updatedOn?.toIso8601String(),
|
||||
'description': instance.description,
|
||||
'full_name': instance.fullName,
|
||||
'slug': instance.slug,
|
||||
'mainbranch': instance.mainbranch,
|
||||
'links': instance.links,
|
||||
};
|
||||
|
||||
BbRepoMainbranch _$BbRepoMainbranchFromJson(Map<String, dynamic> json) =>
|
||||
BbRepoMainbranch()
|
||||
..type = json['type'] as String?
|
||||
..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$BbRepoMainbranchToJson(BbRepoMainbranch instance) =>
|
||||
<String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
BbTree _$BbTreeFromJson(Map<String, dynamic> json) => BbTree(
|
||||
type: json['type'] as String,
|
||||
path: json['path'] as String,
|
||||
)
|
||||
..size = json['size'] as int?
|
||||
..links = json['links'] as Map<String, dynamic>?;
|
||||
|
||||
Map<String, dynamic> _$BbTreeToJson(BbTree instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'links': instance.links,
|
||||
};
|
||||
|
||||
BbCommit _$BbCommitFromJson(Map<String, dynamic> json) => BbCommit()
|
||||
..message = json['message'] as String?
|
||||
..date = json['date'] == null ? null : DateTime.parse(json['date'] as String)
|
||||
..hash = json['hash'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: BbCommitAuthor.fromJson(json['author'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$BbCommitToJson(BbCommit instance) => <String, dynamic>{
|
||||
'message': instance.message,
|
||||
'date': instance.date?.toIso8601String(),
|
||||
'hash': instance.hash,
|
||||
'author': instance.author,
|
||||
};
|
||||
|
||||
BbCommitAuthor _$BbCommitAuthorFromJson(Map<String, dynamic> json) =>
|
||||
BbCommitAuthor()
|
||||
..raw = json['raw'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: BbRepoOwner.fromJson(json['user'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$BbCommitAuthorToJson(BbCommitAuthor instance) =>
|
||||
<String, dynamic>{
|
||||
'raw': instance.raw,
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
BbIssues _$BbIssuesFromJson(Map<String, dynamic> json) => BbIssues()
|
||||
..priority = json['priority'] as String?
|
||||
..state = json['state'] as String?
|
||||
..repository = json['repository'] == null
|
||||
? null
|
||||
: BbRepo.fromJson(json['repository'] as Map<String, dynamic>)
|
||||
..title = json['title'] as String?
|
||||
..reporter = json['reporter'] == null
|
||||
? null
|
||||
: BbRepoOwner.fromJson(json['reporter'] as Map<String, dynamic>)
|
||||
..createdOn = json['created_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_on'] as String)
|
||||
..links = json['links'] as Map<String, dynamic>?;
|
||||
|
||||
Map<String, dynamic> _$BbIssuesToJson(BbIssues instance) => <String, dynamic>{
|
||||
'priority': instance.priority,
|
||||
'state': instance.state,
|
||||
'repository': instance.repository,
|
||||
'title': instance.title,
|
||||
'reporter': instance.reporter,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
'links': instance.links,
|
||||
};
|
||||
|
||||
BbPulls _$BbPullsFromJson(Map<String, dynamic> json) => BbPulls()
|
||||
..description = json['description'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: BbRepoOwner.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..title = json['title'] as String?
|
||||
..links = json['links'] as Map<String, dynamic>?
|
||||
..createdOn = json['created_on'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_on'] as String);
|
||||
|
||||
Map<String, dynamic> _$BbPullsToJson(BbPulls instance) => <String, dynamic>{
|
||||
'description': instance.description,
|
||||
'author': instance.author,
|
||||
'title': instance.title,
|
||||
'links': instance.links,
|
||||
'created_on': instance.createdOn?.toIso8601String(),
|
||||
};
|
||||
|
||||
BbCommentContent _$BbCommentContentFromJson(Map<String, dynamic> json) =>
|
||||
BbCommentContent()
|
||||
..raw = json['raw'] as String?
|
||||
..markup = json['markup'] as String?
|
||||
..html = json['html'] as String?;
|
||||
|
||||
Map<String, dynamic> _$BbCommentContentToJson(BbCommentContent instance) =>
|
||||
<String, dynamic>{
|
||||
'raw': instance.raw,
|
||||
'markup': instance.markup,
|
||||
'html': instance.html,
|
||||
};
|
||||
|
||||
BbComment _$BbCommentFromJson(Map<String, dynamic> json) => BbComment()
|
||||
..createdOn = json['created_on'] as String?
|
||||
..updatedOn = json['updated_on'] as String?
|
||||
..content = json['content'] == null
|
||||
? null
|
||||
: BbCommentContent.fromJson(json['content'] as Map<String, dynamic>)
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: BbRepoOwner.fromJson(json['user'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$BbCommentToJson(BbComment instance) => <String, dynamic>{
|
||||
'created_on': instance.createdOn,
|
||||
'updated_on': instance.updatedOn,
|
||||
'content': instance.content,
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
BbBranch _$BbBranchFromJson(Map<String, dynamic> json) => BbBranch()
|
||||
..name = json['name'] as String?
|
||||
..type = json['type'] as String?;
|
||||
|
||||
Map<String, dynamic> _$BbBranchToJson(BbBranch instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'type': instance.type,
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:fimber/fimber.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_highlight/theme_map.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
@ -8,21 +8,28 @@ import 'package:shared_preferences/shared_preferences.dart';
|
|||
class CodeModel with ChangeNotifier {
|
||||
static var themes = themeMap.keys.toList();
|
||||
static const fontSizes = [12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||
static const fontFamilies = [
|
||||
static final fontFamilies = [
|
||||
'System',
|
||||
'JetBrains Mono',
|
||||
'Fira Code',
|
||||
'Inconsolata',
|
||||
'PT Mono',
|
||||
'Source Code Pro',
|
||||
'Ubuntu Mono',
|
||||
// 'Cascadia Code', // TODO: https://github.com/google/fonts/issues/2179
|
||||
|
||||
// https://fonts.google.com/?category=Monospace
|
||||
...GoogleFonts.asMap().keys.where((element) =>
|
||||
element.endsWith('Mono') ||
|
||||
[
|
||||
'Inconsolata',
|
||||
'Source Code Pro',
|
||||
'Nanum Gothic Coding',
|
||||
'Cousine',
|
||||
'Anonymous Pro',
|
||||
'Courier Prime',
|
||||
'VT323',
|
||||
'Fira Code'
|
||||
].contains(element)),
|
||||
];
|
||||
|
||||
String _theme = 'vs';
|
||||
String _themeDark = 'vs2015';
|
||||
int _fontSize = 14;
|
||||
String _fontFamily = 'JetBrains Mono';
|
||||
String _fontFamily = 'System';
|
||||
|
||||
String get theme => _theme;
|
||||
String get themeDark => _themeDark;
|
||||
|
@ -39,11 +46,11 @@ class CodeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
Future<void> init() async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
var vh = prefs.getString(StorageKeys.codeTheme);
|
||||
var vdh = prefs.getString(StorageKeys.codeThemeDark);
|
||||
var vs = prefs.getInt(StorageKeys.iCodeFontSize);
|
||||
var vf = prefs.getString(StorageKeys.codeFontFamily);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final vh = prefs.getString(StorageKeys.codeTheme);
|
||||
final vdh = prefs.getString(StorageKeys.codeThemeDark);
|
||||
final vs = prefs.getInt(StorageKeys.iCodeFontSize);
|
||||
final vf = prefs.getString(StorageKeys.codeFontFamily);
|
||||
|
||||
Fimber.d('read code: $vh, $vs, $vf');
|
||||
if (themeMap.keys.contains(vh)) {
|
||||
|
@ -63,7 +70,7 @@ class CodeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
setTheme(String v) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.setString(StorageKeys.codeTheme, v);
|
||||
Fimber.d('write code theme: $v');
|
||||
|
@ -73,7 +80,7 @@ class CodeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
setThemeDark(String v) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.setString(StorageKeys.codeThemeDark, v);
|
||||
Fimber.d('write code theme dark: $v');
|
||||
|
@ -83,7 +90,7 @@ class CodeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
setFontSize(int v) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.setInt(StorageKeys.iCodeFontSize, v);
|
||||
Fimber.d('write code font size: $v');
|
||||
|
@ -93,7 +100,7 @@ class CodeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
setFontFamily(String v) async {
|
||||
var prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.setString(StorageKeys.codeFontFamily, v);
|
||||
Fimber.d('write code font family: $v');
|
||||
|
|
|
@ -4,18 +4,21 @@ part 'gitea.g.dart';
|
|||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaUser {
|
||||
GiteaUser();
|
||||
factory GiteaUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaUserFromJson(json);
|
||||
int? id;
|
||||
String? login;
|
||||
String? fullName;
|
||||
String? avatarUrl;
|
||||
DateTime? created;
|
||||
GiteaUser();
|
||||
factory GiteaUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaOrg {
|
||||
GiteaOrg();
|
||||
factory GiteaOrg.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaOrgFromJson(json);
|
||||
int? id;
|
||||
String? username;
|
||||
String? fullName;
|
||||
|
@ -23,13 +26,13 @@ class GiteaOrg {
|
|||
String? description;
|
||||
String? website;
|
||||
String? location;
|
||||
GiteaOrg();
|
||||
factory GiteaOrg.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaOrgFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaRepository {
|
||||
GiteaRepository();
|
||||
factory GiteaRepository.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaRepositoryFromJson(json);
|
||||
int? id;
|
||||
GiteaUser? owner;
|
||||
String? name;
|
||||
|
@ -41,34 +44,33 @@ class GiteaRepository {
|
|||
int? size;
|
||||
int? openIssuesCount;
|
||||
int? openPrCounter;
|
||||
GiteaRepository();
|
||||
factory GiteaRepository.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaRepositoryFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaTree {
|
||||
GiteaTree({required this.type, required this.name});
|
||||
factory GiteaTree.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaTreeFromJson(json);
|
||||
String type;
|
||||
String name;
|
||||
String? path;
|
||||
int? size;
|
||||
String? downloadUrl;
|
||||
GiteaTree({required this.type, required this.name});
|
||||
factory GiteaTree.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaTreeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaBlob extends GiteaTree {
|
||||
String? content;
|
||||
GiteaBlob({required String type, required String name})
|
||||
: super(name: name, type: type);
|
||||
GiteaBlob({required super.type, required super.name});
|
||||
factory GiteaBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaBlobFromJson(json);
|
||||
String? content;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaCommit {
|
||||
GiteaCommit();
|
||||
factory GiteaCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommitFromJson(json);
|
||||
int? number;
|
||||
GiteaUser? author;
|
||||
String? title;
|
||||
|
@ -76,33 +78,33 @@ class GiteaCommit {
|
|||
GiteaCommitDetail? commit;
|
||||
String? sha;
|
||||
String? htmlUrl;
|
||||
GiteaCommit();
|
||||
factory GiteaCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaCommitDetail {
|
||||
String? message;
|
||||
GiteaCommitAuthor? author;
|
||||
GiteaCommitAuthor? committer;
|
||||
GiteaCommitDetail();
|
||||
factory GiteaCommitDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommitDetailFromJson(json);
|
||||
String? message;
|
||||
GiteaCommitAuthor? author;
|
||||
GiteaCommitAuthor? committer;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaCommitAuthor {
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
GiteaCommitAuthor();
|
||||
factory GiteaCommitAuthor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommitAuthorFromJson(json);
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaIssue {
|
||||
GiteaIssue();
|
||||
factory GiteaIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaIssueFromJson(json);
|
||||
String? title;
|
||||
String? body;
|
||||
int? number;
|
||||
|
@ -112,31 +114,31 @@ class GiteaIssue {
|
|||
String? state;
|
||||
String? htmlUrl;
|
||||
List<GiteaLabel>? labels;
|
||||
GiteaIssue();
|
||||
factory GiteaIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaLabel {
|
||||
String? color;
|
||||
String? name;
|
||||
GiteaLabel();
|
||||
factory GiteaLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaLabelFromJson(json);
|
||||
String? color;
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaHeatmapItem {
|
||||
int? timestamp;
|
||||
int? contributions;
|
||||
GiteaHeatmapItem();
|
||||
factory GiteaHeatmapItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaHeatmapItemFromJson(json);
|
||||
int? timestamp;
|
||||
int? contributions;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteaComment {
|
||||
GiteaComment();
|
||||
factory GiteaComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommentFromJson(json);
|
||||
String? body;
|
||||
DateTime? createdAt;
|
||||
String? htmlUrl;
|
||||
|
@ -144,7 +146,4 @@ class GiteaComment {
|
|||
DateTime? updatedAt;
|
||||
int? id;
|
||||
GiteaUser? user;
|
||||
GiteaComment();
|
||||
factory GiteaComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteaCommentFromJson(json);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'gitea.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GiteaUser _$GiteaUserFromJson(Map<String, dynamic> json) => GiteaUser()
|
||||
..id = json['id'] as int?
|
||||
..login = json['login'] as String?
|
||||
..fullName = json['full_name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..created = json['created'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created'] as String);
|
||||
|
||||
Map<String, dynamic> _$GiteaUserToJson(GiteaUser instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'login': instance.login,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'created': instance.created?.toIso8601String(),
|
||||
};
|
||||
|
||||
GiteaOrg _$GiteaOrgFromJson(Map<String, dynamic> json) => GiteaOrg()
|
||||
..id = json['id'] as int?
|
||||
..username = json['username'] as String?
|
||||
..fullName = json['full_name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..website = json['website'] as String?
|
||||
..location = json['location'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteaOrgToJson(GiteaOrg instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'website': instance.website,
|
||||
'location': instance.location,
|
||||
};
|
||||
|
||||
GiteaRepository _$GiteaRepositoryFromJson(Map<String, dynamic> json) =>
|
||||
GiteaRepository()
|
||||
..id = json['id'] as int?
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GiteaUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..name = json['name'] as String?
|
||||
..description = json['description'] as String?
|
||||
..starsCount = json['stars_count'] as int?
|
||||
..forksCount = json['forks_count'] as int?
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..website = json['website'] as String?
|
||||
..size = json['size'] as int?
|
||||
..openIssuesCount = json['open_issues_count'] as int?
|
||||
..openPrCounter = json['open_pr_counter'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteaRepositoryToJson(GiteaRepository instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'owner': instance.owner,
|
||||
'name': instance.name,
|
||||
'description': instance.description,
|
||||
'stars_count': instance.starsCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'website': instance.website,
|
||||
'size': instance.size,
|
||||
'open_issues_count': instance.openIssuesCount,
|
||||
'open_pr_counter': instance.openPrCounter,
|
||||
};
|
||||
|
||||
GiteaTree _$GiteaTreeFromJson(Map<String, dynamic> json) => GiteaTree(
|
||||
type: json['type'] as String,
|
||||
name: json['name'] as String,
|
||||
)
|
||||
..path = json['path'] as String?
|
||||
..size = json['size'] as int?
|
||||
..downloadUrl = json['download_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteaTreeToJson(GiteaTree instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
};
|
||||
|
||||
GiteaBlob _$GiteaBlobFromJson(Map<String, dynamic> json) => GiteaBlob(
|
||||
type: json['type'] as String,
|
||||
name: json['name'] as String,
|
||||
)
|
||||
..path = json['path'] as String?
|
||||
..size = json['size'] as int?
|
||||
..downloadUrl = json['download_url'] as String?
|
||||
..content = json['content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteaBlobToJson(GiteaBlob instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GiteaCommit _$GiteaCommitFromJson(Map<String, dynamic> json) => GiteaCommit()
|
||||
..number = json['number'] as int?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GiteaUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..title = json['title'] as String?
|
||||
..body = json['body'] as String?
|
||||
..commit = json['commit'] == null
|
||||
? null
|
||||
: GiteaCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
||||
..sha = json['sha'] as String?
|
||||
..htmlUrl = json['html_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteaCommitToJson(GiteaCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'number': instance.number,
|
||||
'author': instance.author,
|
||||
'title': instance.title,
|
||||
'body': instance.body,
|
||||
'commit': instance.commit,
|
||||
'sha': instance.sha,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GiteaCommitDetail _$GiteaCommitDetailFromJson(Map<String, dynamic> json) =>
|
||||
GiteaCommitDetail()
|
||||
..message = json['message'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GiteaCommitAuthor.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..committer = json['committer'] == null
|
||||
? null
|
||||
: GiteaCommitAuthor.fromJson(
|
||||
json['committer'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GiteaCommitDetailToJson(GiteaCommitDetail instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message,
|
||||
'author': instance.author,
|
||||
'committer': instance.committer,
|
||||
};
|
||||
|
||||
GiteaCommitAuthor _$GiteaCommitAuthorFromJson(Map<String, dynamic> json) =>
|
||||
GiteaCommitAuthor()
|
||||
..name = json['name'] as String?
|
||||
..email = json['email'] as String?
|
||||
..date =
|
||||
json['date'] == null ? null : DateTime.parse(json['date'] as String);
|
||||
|
||||
Map<String, dynamic> _$GiteaCommitAuthorToJson(GiteaCommitAuthor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'email': instance.email,
|
||||
'date': instance.date?.toIso8601String(),
|
||||
};
|
||||
|
||||
GiteaIssue _$GiteaIssueFromJson(Map<String, dynamic> json) => GiteaIssue()
|
||||
..title = json['title'] as String?
|
||||
..body = json['body'] as String?
|
||||
..number = json['number'] as int?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteaUser.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..comments = json['comments'] as int?
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..state = json['state'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..labels = (json['labels'] as List<dynamic>?)
|
||||
?.map((e) => GiteaLabel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
Map<String, dynamic> _$GiteaIssueToJson(GiteaIssue instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'body': instance.body,
|
||||
'number': instance.number,
|
||||
'user': instance.user,
|
||||
'comments': instance.comments,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'state': instance.state,
|
||||
'html_url': instance.htmlUrl,
|
||||
'labels': instance.labels,
|
||||
};
|
||||
|
||||
GiteaLabel _$GiteaLabelFromJson(Map<String, dynamic> json) => GiteaLabel()
|
||||
..color = json['color'] as String?
|
||||
..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteaLabelToJson(GiteaLabel instance) =>
|
||||
<String, dynamic>{
|
||||
'color': instance.color,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GiteaHeatmapItem _$GiteaHeatmapItemFromJson(Map<String, dynamic> json) =>
|
||||
GiteaHeatmapItem()
|
||||
..timestamp = json['timestamp'] as int?
|
||||
..contributions = json['contributions'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteaHeatmapItemToJson(GiteaHeatmapItem instance) =>
|
||||
<String, dynamic>{
|
||||
'timestamp': instance.timestamp,
|
||||
'contributions': instance.contributions,
|
||||
};
|
||||
|
||||
GiteaComment _$GiteaCommentFromJson(Map<String, dynamic> json) => GiteaComment()
|
||||
..body = json['body'] as String?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..originalAuthor = json['original_author'] as String?
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..id = json['id'] as int?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteaUser.fromJson(json['user'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GiteaCommentToJson(GiteaComment instance) =>
|
||||
<String, dynamic>{
|
||||
'body': instance.body,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'html_url': instance.htmlUrl,
|
||||
'original_author': instance.originalAuthor,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'id': instance.id,
|
||||
'user': instance.user,
|
||||
};
|
|
@ -4,6 +4,9 @@ part 'gitee.g.dart';
|
|||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeUser {
|
||||
GiteeUser();
|
||||
factory GiteeUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeUserFromJson(json);
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
String? name;
|
||||
|
@ -16,24 +19,24 @@ class GiteeUser {
|
|||
int? stared;
|
||||
int? watched;
|
||||
DateTime? createdAt;
|
||||
GiteeUser();
|
||||
factory GiteeUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeListUser {
|
||||
GiteeListUser();
|
||||
factory GiteeListUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeListUserFromJson(json);
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
String? name;
|
||||
String? htmlUrl;
|
||||
GiteeListUser();
|
||||
factory GiteeListUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeListUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeRepo {
|
||||
GiteeRepo();
|
||||
factory GiteeRepo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeRepoFromJson(json);
|
||||
GiteeRepoNamespace? namespace;
|
||||
GiteeRepoOwner? owner;
|
||||
String? path;
|
||||
|
@ -51,90 +54,90 @@ class GiteeRepo {
|
|||
int? openIssuesCount;
|
||||
bool? pullRequestsEnabled;
|
||||
String? defaultBranch;
|
||||
GiteeRepo();
|
||||
factory GiteeRepo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeRepoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeRepoOwner {
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
GiteeRepoOwner();
|
||||
factory GiteeRepoOwner.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeRepoOwnerFromJson(json);
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeRepoNamespace {
|
||||
String? path;
|
||||
GiteeRepoNamespace();
|
||||
factory GiteeRepoNamespace.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeRepoNamespaceFromJson(json);
|
||||
String? path;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeCommit {
|
||||
GiteeCommit();
|
||||
factory GiteeCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitFromJson(json);
|
||||
GiteeUser? author;
|
||||
GiteeCommitDetail? commit;
|
||||
String? sha;
|
||||
String? htmlUrl;
|
||||
List<GiteeCommitFile>? files;
|
||||
GiteeCommit();
|
||||
factory GiteeCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeCommitDetail {
|
||||
String? message;
|
||||
GiteeCommitAuthor? author;
|
||||
GiteeCommitAuthor? committer;
|
||||
GiteeCommitDetail();
|
||||
factory GiteeCommitDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitDetailFromJson(json);
|
||||
String? message;
|
||||
GiteeCommitAuthor? author;
|
||||
GiteeCommitAuthor? committer;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeCommitAuthor {
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
GiteeCommitAuthor();
|
||||
factory GiteeCommitAuthor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitAuthorFromJson(json);
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeTreeItem {
|
||||
GiteeTreeItem({required this.path, required this.type});
|
||||
factory GiteeTreeItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeTreeItemFromJson(json);
|
||||
String path;
|
||||
String type;
|
||||
String? sha;
|
||||
int? size;
|
||||
GiteeTreeItem({required this.path, required this.type});
|
||||
factory GiteeTreeItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeTreeItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeBlob {
|
||||
String? content;
|
||||
GiteeBlob();
|
||||
factory GiteeBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeBlobFromJson(json);
|
||||
String? content;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeLabel {
|
||||
String? color;
|
||||
String? name;
|
||||
GiteeLabel();
|
||||
factory GiteeLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeLabelFromJson(json);
|
||||
String? color;
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeIssue {
|
||||
GiteeIssue();
|
||||
factory GiteeIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeIssueFromJson(json);
|
||||
int? comments;
|
||||
String? commentsUrl;
|
||||
String? createdAt;
|
||||
|
@ -149,13 +152,13 @@ class GiteeIssue {
|
|||
String? number;
|
||||
List<GiteeLabel>? labels;
|
||||
int? id;
|
||||
GiteeIssue();
|
||||
factory GiteeIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteePull {
|
||||
GiteePull();
|
||||
factory GiteePull.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteePullFromJson(json);
|
||||
String? commentsUrl;
|
||||
String? createdAt;
|
||||
String? htmlUrl;
|
||||
|
@ -168,34 +171,34 @@ class GiteePull {
|
|||
List<GiteeLabel>? labels;
|
||||
int? number;
|
||||
int? id;
|
||||
GiteePull();
|
||||
factory GiteePull.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteePullFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeComment {
|
||||
GiteeComment();
|
||||
factory GiteeComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommentFromJson(json);
|
||||
int? id;
|
||||
String? body;
|
||||
String? createdAt;
|
||||
GiteeRepoOwner? user;
|
||||
GiteeComment();
|
||||
factory GiteeComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommentFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteePatch {
|
||||
String? diff;
|
||||
GiteePatch();
|
||||
factory GiteePatch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteePatchFromJson(json);
|
||||
String? diff;
|
||||
}
|
||||
|
||||
// Two different classes because of variable type mismatch
|
||||
// for additions, deletions, patch
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteePullFile {
|
||||
GiteePullFile();
|
||||
factory GiteePullFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteePullFileFromJson(json);
|
||||
String? additions;
|
||||
String? deletions;
|
||||
String? blobUrl;
|
||||
|
@ -203,13 +206,13 @@ class GiteePullFile {
|
|||
String? sha;
|
||||
String? status;
|
||||
GiteePatch? patch;
|
||||
GiteePullFile();
|
||||
factory GiteePullFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteePullFileFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeCommitFile {
|
||||
GiteeCommitFile();
|
||||
factory GiteeCommitFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitFileFromJson(json);
|
||||
int? additions;
|
||||
int? deletions;
|
||||
int? changes;
|
||||
|
@ -218,24 +221,21 @@ class GiteeCommitFile {
|
|||
String? sha;
|
||||
String? status;
|
||||
String? patch;
|
||||
GiteeCommitFile();
|
||||
factory GiteeCommitFile.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeCommitFileFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeContributor {
|
||||
String? name;
|
||||
int? contributions;
|
||||
GiteeContributor();
|
||||
factory GiteeContributor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeContributorFromJson(json);
|
||||
String? name;
|
||||
int? contributions;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GiteeBranch {
|
||||
String? name;
|
||||
GiteeBranch();
|
||||
factory GiteeBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GiteeBranchFromJson(json);
|
||||
String? name;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,366 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'gitee.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GiteeUser _$GiteeUserFromJson(Map<String, dynamic> json) => GiteeUser()
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..name = json['name'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..bio = json['bio'] as String?
|
||||
..blog = json['blog'] as String?
|
||||
..publicRepos = json['public_repos'] as int?
|
||||
..followers = json['followers'] as int?
|
||||
..following = json['following'] as int?
|
||||
..stared = json['stared'] as int?
|
||||
..watched = json['watched'] as int?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String);
|
||||
|
||||
Map<String, dynamic> _$GiteeUserToJson(GiteeUser instance) => <String, dynamic>{
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'name': instance.name,
|
||||
'html_url': instance.htmlUrl,
|
||||
'bio': instance.bio,
|
||||
'blog': instance.blog,
|
||||
'public_repos': instance.publicRepos,
|
||||
'followers': instance.followers,
|
||||
'following': instance.following,
|
||||
'stared': instance.stared,
|
||||
'watched': instance.watched,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
GiteeListUser _$GiteeListUserFromJson(Map<String, dynamic> json) =>
|
||||
GiteeListUser()
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..name = json['name'] as String?
|
||||
..htmlUrl = json['html_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeListUserToJson(GiteeListUser instance) =>
|
||||
<String, dynamic>{
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'name': instance.name,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GiteeRepo _$GiteeRepoFromJson(Map<String, dynamic> json) => GiteeRepo()
|
||||
..namespace = json['namespace'] == null
|
||||
? null
|
||||
: GiteeRepoNamespace.fromJson(json['namespace'] as Map<String, dynamic>)
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GiteeRepoOwner.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..path = json['path'] as String?
|
||||
..description = json['description'] as String?
|
||||
..private = json['private'] as bool?
|
||||
..public = json['public'] as bool?
|
||||
..internal = json['internal'] as bool?
|
||||
..fork = json['fork'] as bool?
|
||||
..forksCount = json['forks_count'] as int?
|
||||
..stargazersCount = json['stargazers_count'] as int?
|
||||
..watchersCount = json['watchers_count'] as int?
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..license = json['license'] as String?
|
||||
..homepage = json['homepage'] as String?
|
||||
..openIssuesCount = json['open_issues_count'] as int?
|
||||
..pullRequestsEnabled = json['pull_requests_enabled'] as bool?
|
||||
..defaultBranch = json['default_branch'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeRepoToJson(GiteeRepo instance) => <String, dynamic>{
|
||||
'namespace': instance.namespace,
|
||||
'owner': instance.owner,
|
||||
'path': instance.path,
|
||||
'description': instance.description,
|
||||
'private': instance.private,
|
||||
'public': instance.public,
|
||||
'internal': instance.internal,
|
||||
'fork': instance.fork,
|
||||
'forks_count': instance.forksCount,
|
||||
'stargazers_count': instance.stargazersCount,
|
||||
'watchers_count': instance.watchersCount,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'license': instance.license,
|
||||
'homepage': instance.homepage,
|
||||
'open_issues_count': instance.openIssuesCount,
|
||||
'pull_requests_enabled': instance.pullRequestsEnabled,
|
||||
'default_branch': instance.defaultBranch,
|
||||
};
|
||||
|
||||
GiteeRepoOwner _$GiteeRepoOwnerFromJson(Map<String, dynamic> json) =>
|
||||
GiteeRepoOwner()
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeRepoOwnerToJson(GiteeRepoOwner instance) =>
|
||||
<String, dynamic>{
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
};
|
||||
|
||||
GiteeRepoNamespace _$GiteeRepoNamespaceFromJson(Map<String, dynamic> json) =>
|
||||
GiteeRepoNamespace()..path = json['path'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeRepoNamespaceToJson(GiteeRepoNamespace instance) =>
|
||||
<String, dynamic>{
|
||||
'path': instance.path,
|
||||
};
|
||||
|
||||
GiteeCommit _$GiteeCommitFromJson(Map<String, dynamic> json) => GiteeCommit()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GiteeUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..commit = json['commit'] == null
|
||||
? null
|
||||
: GiteeCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
||||
..sha = json['sha'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..files = (json['files'] as List<dynamic>?)
|
||||
?.map((e) => GiteeCommitFile.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
Map<String, dynamic> _$GiteeCommitToJson(GiteeCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'commit': instance.commit,
|
||||
'sha': instance.sha,
|
||||
'html_url': instance.htmlUrl,
|
||||
'files': instance.files,
|
||||
};
|
||||
|
||||
GiteeCommitDetail _$GiteeCommitDetailFromJson(Map<String, dynamic> json) =>
|
||||
GiteeCommitDetail()
|
||||
..message = json['message'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GiteeCommitAuthor.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..committer = json['committer'] == null
|
||||
? null
|
||||
: GiteeCommitAuthor.fromJson(
|
||||
json['committer'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GiteeCommitDetailToJson(GiteeCommitDetail instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message,
|
||||
'author': instance.author,
|
||||
'committer': instance.committer,
|
||||
};
|
||||
|
||||
GiteeCommitAuthor _$GiteeCommitAuthorFromJson(Map<String, dynamic> json) =>
|
||||
GiteeCommitAuthor()
|
||||
..name = json['name'] as String?
|
||||
..email = json['email'] as String?
|
||||
..date =
|
||||
json['date'] == null ? null : DateTime.parse(json['date'] as String);
|
||||
|
||||
Map<String, dynamic> _$GiteeCommitAuthorToJson(GiteeCommitAuthor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'email': instance.email,
|
||||
'date': instance.date?.toIso8601String(),
|
||||
};
|
||||
|
||||
GiteeTreeItem _$GiteeTreeItemFromJson(Map<String, dynamic> json) =>
|
||||
GiteeTreeItem(
|
||||
path: json['path'] as String,
|
||||
type: json['type'] as String,
|
||||
)
|
||||
..sha = json['sha'] as String?
|
||||
..size = json['size'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteeTreeItemToJson(GiteeTreeItem instance) =>
|
||||
<String, dynamic>{
|
||||
'path': instance.path,
|
||||
'type': instance.type,
|
||||
'sha': instance.sha,
|
||||
'size': instance.size,
|
||||
};
|
||||
|
||||
GiteeBlob _$GiteeBlobFromJson(Map<String, dynamic> json) =>
|
||||
GiteeBlob()..content = json['content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeBlobToJson(GiteeBlob instance) => <String, dynamic>{
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GiteeLabel _$GiteeLabelFromJson(Map<String, dynamic> json) => GiteeLabel()
|
||||
..color = json['color'] as String?
|
||||
..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeLabelToJson(GiteeLabel instance) =>
|
||||
<String, dynamic>{
|
||||
'color': instance.color,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GiteeIssue _$GiteeIssueFromJson(Map<String, dynamic> json) => GiteeIssue()
|
||||
..comments = json['comments'] as int?
|
||||
..commentsUrl = json['comments_url'] as String?
|
||||
..createdAt = json['created_at'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..updatedAt = json['updated_at'] as String?
|
||||
..body = json['body'] as String?
|
||||
..bodyHtml = json['body_html'] as String?
|
||||
..title = json['title'] as String?
|
||||
..state = json['state'] as String?
|
||||
..repository = json['repository'] == null
|
||||
? null
|
||||
: GiteeRepo.fromJson(json['repository'] as Map<String, dynamic>)
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..number = json['number'] as String?
|
||||
..labels = (json['labels'] as List<dynamic>?)
|
||||
?.map((e) => GiteeLabel.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..id = json['id'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteeIssueToJson(GiteeIssue instance) =>
|
||||
<String, dynamic>{
|
||||
'comments': instance.comments,
|
||||
'comments_url': instance.commentsUrl,
|
||||
'created_at': instance.createdAt,
|
||||
'html_url': instance.htmlUrl,
|
||||
'updated_at': instance.updatedAt,
|
||||
'body': instance.body,
|
||||
'body_html': instance.bodyHtml,
|
||||
'title': instance.title,
|
||||
'state': instance.state,
|
||||
'repository': instance.repository,
|
||||
'user': instance.user,
|
||||
'number': instance.number,
|
||||
'labels': instance.labels,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
GiteePull _$GiteePullFromJson(Map<String, dynamic> json) => GiteePull()
|
||||
..commentsUrl = json['comments_url'] as String?
|
||||
..createdAt = json['created_at'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..updatedAt = json['updated_at'] as String?
|
||||
..body = json['body'] as String?
|
||||
..bodyHtml = json['body_html'] as String?
|
||||
..title = json['title'] as String?
|
||||
..state = json['state'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..labels = (json['labels'] as List<dynamic>?)
|
||||
?.map((e) => GiteeLabel.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..number = json['number'] as int?
|
||||
..id = json['id'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteePullToJson(GiteePull instance) => <String, dynamic>{
|
||||
'comments_url': instance.commentsUrl,
|
||||
'created_at': instance.createdAt,
|
||||
'html_url': instance.htmlUrl,
|
||||
'updated_at': instance.updatedAt,
|
||||
'body': instance.body,
|
||||
'body_html': instance.bodyHtml,
|
||||
'title': instance.title,
|
||||
'state': instance.state,
|
||||
'user': instance.user,
|
||||
'labels': instance.labels,
|
||||
'number': instance.number,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
GiteeComment _$GiteeCommentFromJson(Map<String, dynamic> json) => GiteeComment()
|
||||
..id = json['id'] as int?
|
||||
..body = json['body'] as String?
|
||||
..createdAt = json['created_at'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GiteeRepoOwner.fromJson(json['user'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GiteeCommentToJson(GiteeComment instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'body': instance.body,
|
||||
'created_at': instance.createdAt,
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
GiteePatch _$GiteePatchFromJson(Map<String, dynamic> json) =>
|
||||
GiteePatch()..diff = json['diff'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteePatchToJson(GiteePatch instance) =>
|
||||
<String, dynamic>{
|
||||
'diff': instance.diff,
|
||||
};
|
||||
|
||||
GiteePullFile _$GiteePullFileFromJson(Map<String, dynamic> json) =>
|
||||
GiteePullFile()
|
||||
..additions = json['additions'] as String?
|
||||
..deletions = json['deletions'] as String?
|
||||
..blobUrl = json['blob_url'] as String?
|
||||
..filename = json['filename'] as String?
|
||||
..sha = json['sha'] as String?
|
||||
..status = json['status'] as String?
|
||||
..patch = json['patch'] == null
|
||||
? null
|
||||
: GiteePatch.fromJson(json['patch'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GiteePullFileToJson(GiteePullFile instance) =>
|
||||
<String, dynamic>{
|
||||
'additions': instance.additions,
|
||||
'deletions': instance.deletions,
|
||||
'blob_url': instance.blobUrl,
|
||||
'filename': instance.filename,
|
||||
'sha': instance.sha,
|
||||
'status': instance.status,
|
||||
'patch': instance.patch,
|
||||
};
|
||||
|
||||
GiteeCommitFile _$GiteeCommitFileFromJson(Map<String, dynamic> json) =>
|
||||
GiteeCommitFile()
|
||||
..additions = json['additions'] as int?
|
||||
..deletions = json['deletions'] as int?
|
||||
..changes = json['changes'] as int?
|
||||
..blobUrl = json['blob_url'] as String?
|
||||
..filename = json['filename'] as String?
|
||||
..sha = json['sha'] as String?
|
||||
..status = json['status'] as String?
|
||||
..patch = json['patch'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeCommitFileToJson(GiteeCommitFile instance) =>
|
||||
<String, dynamic>{
|
||||
'additions': instance.additions,
|
||||
'deletions': instance.deletions,
|
||||
'changes': instance.changes,
|
||||
'blob_url': instance.blobUrl,
|
||||
'filename': instance.filename,
|
||||
'sha': instance.sha,
|
||||
'status': instance.status,
|
||||
'patch': instance.patch,
|
||||
};
|
||||
|
||||
GiteeContributor _$GiteeContributorFromJson(Map<String, dynamic> json) =>
|
||||
GiteeContributor()
|
||||
..name = json['name'] as String?
|
||||
..contributions = json['contributions'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GiteeContributorToJson(GiteeContributor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'contributions': instance.contributions,
|
||||
};
|
||||
|
||||
GiteeBranch _$GiteeBranchFromJson(Map<String, dynamic> json) =>
|
||||
GiteeBranch()..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GiteeBranchToJson(GiteeBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
};
|
|
@ -6,6 +6,10 @@ part 'github.g.dart';
|
|||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEvent {
|
||||
GithubEvent();
|
||||
|
||||
factory GithubEvent.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventFromJson(json);
|
||||
GithubEventUser? actor;
|
||||
String? type;
|
||||
GithubEventRepo? repo;
|
||||
|
@ -22,36 +26,33 @@ class GithubEvent {
|
|||
_repo ??= parseRepositoryFullName(repo!.name!);
|
||||
return _repo!.item2;
|
||||
}
|
||||
|
||||
GithubEvent();
|
||||
|
||||
factory GithubEvent.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventUser {
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
|
||||
GithubEventUser();
|
||||
|
||||
factory GithubEventUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventUserFromJson(json);
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventRepo {
|
||||
String? name;
|
||||
|
||||
GithubEventRepo();
|
||||
|
||||
factory GithubEventRepo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventRepoFromJson(json);
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventPayload {
|
||||
GithubEventPayload();
|
||||
|
||||
factory GithubEventPayload.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventPayloadFromJson(json);
|
||||
GithubEventIssue? issue;
|
||||
GithubEventIssue? pullRequest;
|
||||
GithubEventComment? comment;
|
||||
|
@ -72,14 +73,14 @@ class GithubEventPayload {
|
|||
GithubCheckrunItem? checkRun;
|
||||
GithubCheckSuiteItem? checkSuite;
|
||||
GithubContentReferenceItem? contentReference;
|
||||
GithubEventPayload();
|
||||
|
||||
factory GithubEventPayload.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventPayloadFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventIssue {
|
||||
GithubEventIssue();
|
||||
|
||||
factory GithubEventIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventIssueFromJson(json);
|
||||
String? title;
|
||||
GithubEventUser? user;
|
||||
int? number;
|
||||
|
@ -91,51 +92,47 @@ class GithubEventIssue {
|
|||
DateTime? createdAt;
|
||||
|
||||
bool get isPullRequestComment => pullRequest != null;
|
||||
|
||||
GithubEventIssue();
|
||||
|
||||
factory GithubEventIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventComment {
|
||||
String? body;
|
||||
GithubEventUser? user;
|
||||
String? commitId;
|
||||
String? htmlUrl;
|
||||
|
||||
GithubEventComment();
|
||||
|
||||
factory GithubEventComment.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventCommentFromJson(json);
|
||||
String? body;
|
||||
GithubEventUser? user;
|
||||
String? commitId;
|
||||
String? htmlUrl;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventCommit {
|
||||
String? sha;
|
||||
String? message;
|
||||
|
||||
GithubEventCommit();
|
||||
|
||||
factory GithubEventCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventCommitFromJson(json);
|
||||
String? sha;
|
||||
String? message;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubEventRelease {
|
||||
String? htmlUrl;
|
||||
String? tagName;
|
||||
|
||||
GithubEventRelease();
|
||||
|
||||
factory GithubEventRelease.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubEventReleaseFromJson(json);
|
||||
String? htmlUrl;
|
||||
String? tagName;
|
||||
}
|
||||
|
||||
// Notification
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubNotificationItem {
|
||||
GithubNotificationItem();
|
||||
|
||||
factory GithubNotificationItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemFromJson(json);
|
||||
String? id;
|
||||
GithubNotificationItemSubject? subject;
|
||||
DateTime? updatedAt;
|
||||
|
@ -146,15 +143,14 @@ class GithubNotificationItem {
|
|||
String? state;
|
||||
|
||||
String get key => '_$hashCode';
|
||||
|
||||
GithubNotificationItem();
|
||||
|
||||
factory GithubNotificationItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubNotificationItemSubject {
|
||||
GithubNotificationItemSubject();
|
||||
|
||||
factory GithubNotificationItemSubject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemSubjectFromJson(json);
|
||||
String? title;
|
||||
String? type;
|
||||
String? url;
|
||||
|
@ -164,15 +160,14 @@ class GithubNotificationItemSubject {
|
|||
_number ??= int.parse(url?.split('/').last ?? '0');
|
||||
return _number;
|
||||
}
|
||||
|
||||
GithubNotificationItemSubject();
|
||||
|
||||
factory GithubNotificationItemSubject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemSubjectFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubNotificationItemRepo {
|
||||
GithubNotificationItemRepo();
|
||||
|
||||
factory GithubNotificationItemRepo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemRepoFromJson(json);
|
||||
String? fullName;
|
||||
|
||||
Tuple2<String, String>? _repo;
|
||||
|
@ -185,137 +180,132 @@ class GithubNotificationItemRepo {
|
|||
_repo ??= parseRepositoryFullName(fullName!);
|
||||
return _repo!.item2;
|
||||
}
|
||||
|
||||
GithubNotificationItemRepo();
|
||||
|
||||
factory GithubNotificationItemRepo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubNotificationItemRepoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubTreeItem {
|
||||
GithubTreeItem();
|
||||
factory GithubTreeItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubTreeItemFromJson(json);
|
||||
String? name;
|
||||
String? path;
|
||||
int? size;
|
||||
String? type;
|
||||
String? downloadUrl;
|
||||
String? content;
|
||||
GithubTreeItem();
|
||||
factory GithubTreeItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubTreeItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubPagesItem {
|
||||
String? pageName;
|
||||
String? title;
|
||||
String? action;
|
||||
GithubPagesItem();
|
||||
factory GithubPagesItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubPagesItemFromJson(json);
|
||||
String? pageName;
|
||||
String? title;
|
||||
String? action;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubSecurityItem {
|
||||
String? summary;
|
||||
String? description;
|
||||
String? severity;
|
||||
GithubSecurityItem();
|
||||
factory GithubSecurityItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubSecurityItemFromJson(json);
|
||||
String? summary;
|
||||
String? description;
|
||||
String? severity;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubAlertItem {
|
||||
String? affectedPackageName;
|
||||
String? affectedRange;
|
||||
GithubAlertItem();
|
||||
factory GithubAlertItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubAlertItemFromJson(json);
|
||||
String? affectedPackageName;
|
||||
String? affectedRange;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubProjectItem {
|
||||
GithubProjectItem();
|
||||
factory GithubProjectItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubProjectItemFromJson(json);
|
||||
String? name;
|
||||
String? state;
|
||||
String? body;
|
||||
String? htmlUrl;
|
||||
GithubProjectItem();
|
||||
factory GithubProjectItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubProjectItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubProjectColumnItem {
|
||||
String? htmlUrl;
|
||||
String? columnsUrl;
|
||||
String? name;
|
||||
GithubProjectColumnItem();
|
||||
factory GithubProjectColumnItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubProjectColumnItemFromJson(json);
|
||||
String? htmlUrl;
|
||||
String? columnsUrl;
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubInstallationRepositoriesItem {
|
||||
List<GithubNotificationItemRepo>? repositoriesAdded, repositoriesRemoved;
|
||||
String? repositoriesSelection;
|
||||
int? id;
|
||||
GithubInstallationRepositoriesItem();
|
||||
factory GithubInstallationRepositoriesItem.fromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$GithubInstallationRepositoriesItemFromJson(json);
|
||||
List<GithubNotificationItemRepo>? repositoriesAdded, repositoriesRemoved;
|
||||
String? repositoriesSelection;
|
||||
int? id;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubCheckrunItem {
|
||||
String? status;
|
||||
String? name;
|
||||
int? id;
|
||||
GithubCheckrunItem();
|
||||
factory GithubCheckrunItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubCheckrunItemFromJson(json);
|
||||
String? status;
|
||||
String? name;
|
||||
int? id;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubCheckSuiteItem {
|
||||
String? status;
|
||||
String? conclusion;
|
||||
GithubCheckSuiteItem();
|
||||
factory GithubCheckSuiteItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubCheckSuiteItemFromJson(json);
|
||||
String? status;
|
||||
String? conclusion;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubContentReferenceItem {
|
||||
int? id;
|
||||
String? reference;
|
||||
GithubContentReferenceItem();
|
||||
factory GithubContentReferenceItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubContentReferenceItemFromJson(json);
|
||||
int? id;
|
||||
String? reference;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubContributorItem {
|
||||
GithubContributorItem();
|
||||
factory GithubContributorItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubContributorItemFromJson(json);
|
||||
int? id;
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
String? htmlUrl;
|
||||
int? contributions;
|
||||
GithubContributorItem();
|
||||
factory GithubContributorItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubContributorItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubUserOrganizationItem {
|
||||
GithubUserOrganizationItem();
|
||||
factory GithubUserOrganizationItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubUserOrganizationItemFromJson(json);
|
||||
int? id;
|
||||
String? login;
|
||||
String? avatarUrl;
|
||||
String? description;
|
||||
String? url;
|
||||
GithubUserOrganizationItem();
|
||||
factory GithubUserOrganizationItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubUserOrganizationItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
|
@ -329,6 +319,9 @@ class GistFiles {
|
|||
this.truncated,
|
||||
this.content,
|
||||
});
|
||||
|
||||
factory GistFiles.fromJson(Map<String, dynamic> json) =>
|
||||
_$GistFilesFromJson(json);
|
||||
String? filename;
|
||||
int? size;
|
||||
String? rawUrl;
|
||||
|
@ -336,21 +329,21 @@ class GistFiles {
|
|||
String? language;
|
||||
bool? truncated;
|
||||
String? content;
|
||||
|
||||
factory GistFiles.fromJson(Map<String, dynamic> json) =>
|
||||
_$GistFilesFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubGistsItem {
|
||||
GithubGistsItem();
|
||||
factory GithubGistsItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubGistsItemFromJson(json);
|
||||
String? id;
|
||||
String? description;
|
||||
bool? public;
|
||||
Map<String, GistFiles>? files;
|
||||
GithubEventUser? owner;
|
||||
List<GistFiles> get fileNames {
|
||||
List<GistFiles> filenames = [];
|
||||
files!.forEach((String key, GistFiles value) {
|
||||
final filenames = <GistFiles>[];
|
||||
files!.forEach((key, value) {
|
||||
filenames.add(value);
|
||||
});
|
||||
return filenames;
|
||||
|
@ -358,32 +351,28 @@ class GithubGistsItem {
|
|||
|
||||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
|
||||
GithubGistsItem();
|
||||
factory GithubGistsItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubGistsItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubFilesItem {
|
||||
GithubFilesItem();
|
||||
factory GithubFilesItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubFilesItemFromJson(json);
|
||||
String? filename;
|
||||
String? status;
|
||||
int? additions;
|
||||
int? deletions;
|
||||
int? changes;
|
||||
String? patch;
|
||||
GithubFilesItem();
|
||||
factory GithubFilesItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubFilesItemFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GithubComparisonItem {
|
||||
GithubComparisonItem();
|
||||
factory GithubComparisonItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubComparisonItemFromJson(json);
|
||||
List<GithubFilesItem>? files;
|
||||
String? status;
|
||||
int? aheadBy;
|
||||
int? behindBy;
|
||||
GithubComparisonItem();
|
||||
factory GithubComparisonItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GithubComparisonItemFromJson(json);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,525 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'github.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GithubEvent _$GithubEventFromJson(Map<String, dynamic> json) => GithubEvent()
|
||||
..actor = json['actor'] == null
|
||||
? null
|
||||
: GithubEventUser.fromJson(json['actor'] as Map<String, dynamic>)
|
||||
..type = json['type'] as String?
|
||||
..repo = json['repo'] == null
|
||||
? null
|
||||
: GithubEventRepo.fromJson(json['repo'] as Map<String, dynamic>)
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..payload = json['payload'] == null
|
||||
? null
|
||||
: GithubEventPayload.fromJson(json['payload'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GithubEventToJson(GithubEvent instance) =>
|
||||
<String, dynamic>{
|
||||
'actor': instance.actor,
|
||||
'type': instance.type,
|
||||
'repo': instance.repo,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'payload': instance.payload,
|
||||
};
|
||||
|
||||
GithubEventUser _$GithubEventUserFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventUser()
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubEventUserToJson(GithubEventUser instance) =>
|
||||
<String, dynamic>{
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
};
|
||||
|
||||
GithubEventRepo _$GithubEventRepoFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventRepo()..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubEventRepoToJson(GithubEventRepo instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GithubEventPayload _$GithubEventPayloadFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventPayload()
|
||||
..issue = json['issue'] == null
|
||||
? null
|
||||
: GithubEventIssue.fromJson(json['issue'] as Map<String, dynamic>)
|
||||
..pullRequest = json['pull_request'] == null
|
||||
? null
|
||||
: GithubEventIssue.fromJson(
|
||||
json['pull_request'] as Map<String, dynamic>)
|
||||
..comment = json['comment'] == null
|
||||
? null
|
||||
: GithubEventComment.fromJson(json['comment'] as Map<String, dynamic>)
|
||||
..release = json['release'] == null
|
||||
? null
|
||||
: GithubEventRelease.fromJson(json['release'] as Map<String, dynamic>)
|
||||
..action = json['action'] as String?
|
||||
..ref = json['ref'] as String?
|
||||
..refType = json['ref_type'] as String?
|
||||
..before = json['before'] as String?
|
||||
..head = json['head'] as String?
|
||||
..commits = (json['commits'] as List<dynamic>?)
|
||||
?.map((e) => GithubEventCommit.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..forkee = json['forkee'] as Map<String, dynamic>?
|
||||
..pages = (json['pages'] as List<dynamic>?)
|
||||
?.map((e) => GithubPagesItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..securityAdvisory = json['security_advisory'] == null
|
||||
? null
|
||||
: GithubSecurityItem.fromJson(
|
||||
json['security_advisory'] as Map<String, dynamic>)
|
||||
..alert = json['alert'] == null
|
||||
? null
|
||||
: GithubAlertItem.fromJson(json['alert'] as Map<String, dynamic>)
|
||||
..project = json['project'] == null
|
||||
? null
|
||||
: GithubProjectItem.fromJson(json['project'] as Map<String, dynamic>)
|
||||
..projectColumn = json['project_column'] == null
|
||||
? null
|
||||
: GithubProjectColumnItem.fromJson(
|
||||
json['project_column'] as Map<String, dynamic>)
|
||||
..installation = json['installation'] == null
|
||||
? null
|
||||
: GithubInstallationRepositoriesItem.fromJson(
|
||||
json['installation'] as Map<String, dynamic>)
|
||||
..checkRun = json['check_run'] == null
|
||||
? null
|
||||
: GithubCheckrunItem.fromJson(
|
||||
json['check_run'] as Map<String, dynamic>)
|
||||
..checkSuite = json['check_suite'] == null
|
||||
? null
|
||||
: GithubCheckSuiteItem.fromJson(
|
||||
json['check_suite'] as Map<String, dynamic>)
|
||||
..contentReference = json['content_reference'] == null
|
||||
? null
|
||||
: GithubContentReferenceItem.fromJson(
|
||||
json['content_reference'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GithubEventPayloadToJson(GithubEventPayload instance) =>
|
||||
<String, dynamic>{
|
||||
'issue': instance.issue,
|
||||
'pull_request': instance.pullRequest,
|
||||
'comment': instance.comment,
|
||||
'release': instance.release,
|
||||
'action': instance.action,
|
||||
'ref': instance.ref,
|
||||
'ref_type': instance.refType,
|
||||
'before': instance.before,
|
||||
'head': instance.head,
|
||||
'commits': instance.commits,
|
||||
'forkee': instance.forkee,
|
||||
'pages': instance.pages,
|
||||
'security_advisory': instance.securityAdvisory,
|
||||
'alert': instance.alert,
|
||||
'project': instance.project,
|
||||
'project_column': instance.projectColumn,
|
||||
'installation': instance.installation,
|
||||
'check_run': instance.checkRun,
|
||||
'check_suite': instance.checkSuite,
|
||||
'content_reference': instance.contentReference,
|
||||
};
|
||||
|
||||
GithubEventIssue _$GithubEventIssueFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventIssue()
|
||||
..title = json['title'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GithubEventUser.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..number = json['number'] as int?
|
||||
..body = json['body'] as String?
|
||||
..pullRequest = json['pull_request']
|
||||
..state = json['state'] as String?
|
||||
..comments = json['comments'] as int?
|
||||
..merged = json['merged'] as bool?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String);
|
||||
|
||||
Map<String, dynamic> _$GithubEventIssueToJson(GithubEventIssue instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'user': instance.user,
|
||||
'number': instance.number,
|
||||
'body': instance.body,
|
||||
'pull_request': instance.pullRequest,
|
||||
'state': instance.state,
|
||||
'comments': instance.comments,
|
||||
'merged': instance.merged,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
GithubEventComment _$GithubEventCommentFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventComment()
|
||||
..body = json['body'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GithubEventUser.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..commitId = json['commit_id'] as String?
|
||||
..htmlUrl = json['html_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubEventCommentToJson(GithubEventComment instance) =>
|
||||
<String, dynamic>{
|
||||
'body': instance.body,
|
||||
'user': instance.user,
|
||||
'commit_id': instance.commitId,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GithubEventCommit _$GithubEventCommitFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventCommit()
|
||||
..sha = json['sha'] as String?
|
||||
..message = json['message'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubEventCommitToJson(GithubEventCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'sha': instance.sha,
|
||||
'message': instance.message,
|
||||
};
|
||||
|
||||
GithubEventRelease _$GithubEventReleaseFromJson(Map<String, dynamic> json) =>
|
||||
GithubEventRelease()
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..tagName = json['tag_name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubEventReleaseToJson(GithubEventRelease instance) =>
|
||||
<String, dynamic>{
|
||||
'html_url': instance.htmlUrl,
|
||||
'tag_name': instance.tagName,
|
||||
};
|
||||
|
||||
GithubNotificationItem _$GithubNotificationItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubNotificationItem()
|
||||
..id = json['id'] as String?
|
||||
..subject = json['subject'] == null
|
||||
? null
|
||||
: GithubNotificationItemSubject.fromJson(
|
||||
json['subject'] as Map<String, dynamic>)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..repository = json['repository'] == null
|
||||
? null
|
||||
: GithubNotificationItemRepo.fromJson(
|
||||
json['repository'] as Map<String, dynamic>)
|
||||
..unread = json['unread'] as bool?;
|
||||
|
||||
Map<String, dynamic> _$GithubNotificationItemToJson(
|
||||
GithubNotificationItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'subject': instance.subject,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'repository': instance.repository,
|
||||
'unread': instance.unread,
|
||||
};
|
||||
|
||||
GithubNotificationItemSubject _$GithubNotificationItemSubjectFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubNotificationItemSubject()
|
||||
..title = json['title'] as String?
|
||||
..type = json['type'] as String?
|
||||
..url = json['url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubNotificationItemSubjectToJson(
|
||||
GithubNotificationItemSubject instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'type': instance.type,
|
||||
'url': instance.url,
|
||||
};
|
||||
|
||||
GithubNotificationItemRepo _$GithubNotificationItemRepoFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubNotificationItemRepo()..fullName = json['full_name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubNotificationItemRepoToJson(
|
||||
GithubNotificationItemRepo instance) =>
|
||||
<String, dynamic>{
|
||||
'full_name': instance.fullName,
|
||||
};
|
||||
|
||||
GithubTreeItem _$GithubTreeItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubTreeItem()
|
||||
..name = json['name'] as String?
|
||||
..path = json['path'] as String?
|
||||
..size = json['size'] as int?
|
||||
..type = json['type'] as String?
|
||||
..downloadUrl = json['download_url'] as String?
|
||||
..content = json['content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubTreeItemToJson(GithubTreeItem instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'type': instance.type,
|
||||
'download_url': instance.downloadUrl,
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GithubPagesItem _$GithubPagesItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubPagesItem()
|
||||
..pageName = json['page_name'] as String?
|
||||
..title = json['title'] as String?
|
||||
..action = json['action'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubPagesItemToJson(GithubPagesItem instance) =>
|
||||
<String, dynamic>{
|
||||
'page_name': instance.pageName,
|
||||
'title': instance.title,
|
||||
'action': instance.action,
|
||||
};
|
||||
|
||||
GithubSecurityItem _$GithubSecurityItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubSecurityItem()
|
||||
..summary = json['summary'] as String?
|
||||
..description = json['description'] as String?
|
||||
..severity = json['severity'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubSecurityItemToJson(GithubSecurityItem instance) =>
|
||||
<String, dynamic>{
|
||||
'summary': instance.summary,
|
||||
'description': instance.description,
|
||||
'severity': instance.severity,
|
||||
};
|
||||
|
||||
GithubAlertItem _$GithubAlertItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubAlertItem()
|
||||
..affectedPackageName = json['affected_package_name'] as String?
|
||||
..affectedRange = json['affected_range'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubAlertItemToJson(GithubAlertItem instance) =>
|
||||
<String, dynamic>{
|
||||
'affected_package_name': instance.affectedPackageName,
|
||||
'affected_range': instance.affectedRange,
|
||||
};
|
||||
|
||||
GithubProjectItem _$GithubProjectItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubProjectItem()
|
||||
..name = json['name'] as String?
|
||||
..state = json['state'] as String?
|
||||
..body = json['body'] as String?
|
||||
..htmlUrl = json['html_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubProjectItemToJson(GithubProjectItem instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'state': instance.state,
|
||||
'body': instance.body,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GithubProjectColumnItem _$GithubProjectColumnItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubProjectColumnItem()
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..columnsUrl = json['columns_url'] as String?
|
||||
..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubProjectColumnItemToJson(
|
||||
GithubProjectColumnItem instance) =>
|
||||
<String, dynamic>{
|
||||
'html_url': instance.htmlUrl,
|
||||
'columns_url': instance.columnsUrl,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GithubInstallationRepositoriesItem _$GithubInstallationRepositoriesItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubInstallationRepositoriesItem()
|
||||
..repositoriesAdded = (json['repositories_added'] as List<dynamic>?)
|
||||
?.map((e) =>
|
||||
GithubNotificationItemRepo.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..repositoriesRemoved = (json['repositories_removed'] as List<dynamic>?)
|
||||
?.map((e) =>
|
||||
GithubNotificationItemRepo.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..repositoriesSelection = json['repositories_selection'] as String?
|
||||
..id = json['id'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GithubInstallationRepositoriesItemToJson(
|
||||
GithubInstallationRepositoriesItem instance) =>
|
||||
<String, dynamic>{
|
||||
'repositories_added': instance.repositoriesAdded,
|
||||
'repositories_removed': instance.repositoriesRemoved,
|
||||
'repositories_selection': instance.repositoriesSelection,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
GithubCheckrunItem _$GithubCheckrunItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubCheckrunItem()
|
||||
..status = json['status'] as String?
|
||||
..name = json['name'] as String?
|
||||
..id = json['id'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GithubCheckrunItemToJson(GithubCheckrunItem instance) =>
|
||||
<String, dynamic>{
|
||||
'status': instance.status,
|
||||
'name': instance.name,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
GithubCheckSuiteItem _$GithubCheckSuiteItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubCheckSuiteItem()
|
||||
..status = json['status'] as String?
|
||||
..conclusion = json['conclusion'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubCheckSuiteItemToJson(
|
||||
GithubCheckSuiteItem instance) =>
|
||||
<String, dynamic>{
|
||||
'status': instance.status,
|
||||
'conclusion': instance.conclusion,
|
||||
};
|
||||
|
||||
GithubContentReferenceItem _$GithubContentReferenceItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubContentReferenceItem()
|
||||
..id = json['id'] as int?
|
||||
..reference = json['reference'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubContentReferenceItemToJson(
|
||||
GithubContentReferenceItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'reference': instance.reference,
|
||||
};
|
||||
|
||||
GithubContributorItem _$GithubContributorItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubContributorItem()
|
||||
..id = json['id'] as int?
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..contributions = json['contributions'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GithubContributorItemToJson(
|
||||
GithubContributorItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'html_url': instance.htmlUrl,
|
||||
'contributions': instance.contributions,
|
||||
};
|
||||
|
||||
GithubUserOrganizationItem _$GithubUserOrganizationItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubUserOrganizationItem()
|
||||
..id = json['id'] as int?
|
||||
..login = json['login'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..url = json['url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubUserOrganizationItemToJson(
|
||||
GithubUserOrganizationItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'login': instance.login,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'url': instance.url,
|
||||
};
|
||||
|
||||
GistFiles _$GistFilesFromJson(Map<String, dynamic> json) => GistFiles(
|
||||
filename: json['filename'] as String?,
|
||||
size: json['size'] as int?,
|
||||
rawUrl: json['raw_url'] as String?,
|
||||
type: json['type'] as String?,
|
||||
language: json['language'] as String?,
|
||||
truncated: json['truncated'] as bool?,
|
||||
content: json['content'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GistFilesToJson(GistFiles instance) => <String, dynamic>{
|
||||
'filename': instance.filename,
|
||||
'size': instance.size,
|
||||
'raw_url': instance.rawUrl,
|
||||
'type': instance.type,
|
||||
'language': instance.language,
|
||||
'truncated': instance.truncated,
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GithubGistsItem _$GithubGistsItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubGistsItem()
|
||||
..id = json['id'] as String?
|
||||
..description = json['description'] as String?
|
||||
..public = json['public'] as bool?
|
||||
..files = (json['files'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) => MapEntry(k, GistFiles.fromJson(e as Map<String, dynamic>)),
|
||||
)
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GithubEventUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String);
|
||||
|
||||
Map<String, dynamic> _$GithubGistsItemToJson(GithubGistsItem instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'description': instance.description,
|
||||
'public': instance.public,
|
||||
'files': instance.files,
|
||||
'owner': instance.owner,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
GithubFilesItem _$GithubFilesItemFromJson(Map<String, dynamic> json) =>
|
||||
GithubFilesItem()
|
||||
..filename = json['filename'] as String?
|
||||
..status = json['status'] as String?
|
||||
..additions = json['additions'] as int?
|
||||
..deletions = json['deletions'] as int?
|
||||
..changes = json['changes'] as int?
|
||||
..patch = json['patch'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GithubFilesItemToJson(GithubFilesItem instance) =>
|
||||
<String, dynamic>{
|
||||
'filename': instance.filename,
|
||||
'status': instance.status,
|
||||
'additions': instance.additions,
|
||||
'deletions': instance.deletions,
|
||||
'changes': instance.changes,
|
||||
'patch': instance.patch,
|
||||
};
|
||||
|
||||
GithubComparisonItem _$GithubComparisonItemFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GithubComparisonItem()
|
||||
..files = (json['files'] as List<dynamic>?)
|
||||
?.map((e) => GithubFilesItem.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..status = json['status'] as String?
|
||||
..aheadBy = json['ahead_by'] as int?
|
||||
..behindBy = json['behind_by'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GithubComparisonItemToJson(
|
||||
GithubComparisonItem instance) =>
|
||||
<String, dynamic>{
|
||||
'files': instance.files,
|
||||
'status': instance.status,
|
||||
'ahead_by': instance.aheadBy,
|
||||
'behind_by': instance.behindBy,
|
||||
};
|
|
@ -4,6 +4,9 @@ part 'gitlab.g.dart';
|
|||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabUser {
|
||||
GitlabUser();
|
||||
factory GitlabUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabUserFromJson(json);
|
||||
int? id;
|
||||
String? username;
|
||||
String? name;
|
||||
|
@ -11,70 +14,70 @@ class GitlabUser {
|
|||
String? bio;
|
||||
DateTime? createdAt;
|
||||
int? accessLevel;
|
||||
GitlabUser();
|
||||
factory GitlabUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabGroup {
|
||||
GitlabGroup();
|
||||
factory GitlabGroup.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabGroupFromJson(json);
|
||||
int? id;
|
||||
String? path;
|
||||
String? name;
|
||||
String? avatarUrl;
|
||||
String? description;
|
||||
List<GitlabProject>? projects;
|
||||
GitlabGroup();
|
||||
factory GitlabGroup.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabGroupFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabTodoProject {
|
||||
String? pathWithNamespace;
|
||||
GitlabTodoProject();
|
||||
factory GitlabTodoProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTodoProjectFromJson(json);
|
||||
String? pathWithNamespace;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabTodo {
|
||||
GitlabTodo();
|
||||
factory GitlabTodo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTodoFromJson(json);
|
||||
GitlabUser? author;
|
||||
GitlabTodoProject? project;
|
||||
String? actionName;
|
||||
String? targetType;
|
||||
GitlabTodoTarget? target;
|
||||
GitlabTodo();
|
||||
factory GitlabTodo.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTodoFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabTodoTarget {
|
||||
GitlabTodoTarget();
|
||||
factory GitlabTodoTarget.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTodoTargetFromJson(json);
|
||||
int? iid;
|
||||
int? projectId;
|
||||
String? title;
|
||||
GitlabUser? author;
|
||||
String? description;
|
||||
DateTime? createdAt;
|
||||
GitlabTodoTarget();
|
||||
factory GitlabTodoTarget.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTodoTargetFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabIssueNote {
|
||||
GitlabIssueNote();
|
||||
factory GitlabIssueNote.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabIssueNoteFromJson(json);
|
||||
GitlabUser? author;
|
||||
String? body;
|
||||
bool? system;
|
||||
DateTime? createdAt;
|
||||
GitlabIssueNote();
|
||||
factory GitlabIssueNote.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabIssueNoteFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProject {
|
||||
GitlabProject();
|
||||
factory GitlabProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectFromJson(json);
|
||||
int? id;
|
||||
String? name;
|
||||
String? avatarUrl;
|
||||
|
@ -93,103 +96,103 @@ class GitlabProject {
|
|||
DateTime? lastActivityAt;
|
||||
DateTime? createdAt;
|
||||
String? defaultBranch;
|
||||
GitlabProject();
|
||||
factory GitlabProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectBadge {
|
||||
String? renderedImageUrl;
|
||||
GitlabProjectBadge();
|
||||
factory GitlabProjectBadge.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectBadgeFromJson(json);
|
||||
String? renderedImageUrl;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectStatistics {
|
||||
int? commitCount;
|
||||
int? repositorySize;
|
||||
GitlabProjectStatistics();
|
||||
factory GitlabProjectStatistics.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectStatisticsFromJson(json);
|
||||
int? commitCount;
|
||||
int? repositorySize;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabProjectNamespace {
|
||||
GitlabProjectNamespace();
|
||||
factory GitlabProjectNamespace.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectNamespaceFromJson(json);
|
||||
int? id;
|
||||
String? name;
|
||||
String? path;
|
||||
String? kind;
|
||||
GitlabProjectNamespace();
|
||||
factory GitlabProjectNamespace.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabProjectNamespaceFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabTreeItem {
|
||||
String type;
|
||||
String path;
|
||||
String name;
|
||||
GitlabTreeItem({required this.type, required this.path, required this.name});
|
||||
factory GitlabTreeItem.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabTreeItemFromJson(json);
|
||||
String type;
|
||||
String path;
|
||||
String name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabBlob {
|
||||
String? content;
|
||||
GitlabBlob();
|
||||
factory GitlabBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabBlobFromJson(json);
|
||||
String? content;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabEvent {
|
||||
GitlabEvent();
|
||||
factory GitlabEvent.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabEventFromJson(json);
|
||||
GitlabUser? author;
|
||||
String? actionName;
|
||||
String? targetType;
|
||||
GitlabEventNote? note;
|
||||
GitlabEvent();
|
||||
factory GitlabEvent.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabEventFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabEventNote {
|
||||
String? body;
|
||||
String? noteableType;
|
||||
int? noteableIid;
|
||||
GitlabEventNote();
|
||||
factory GitlabEventNote.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabEventNoteFromJson(json);
|
||||
String? body;
|
||||
String? noteableType;
|
||||
int? noteableIid;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabCommit {
|
||||
GitlabCommit();
|
||||
factory GitlabCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabCommitFromJson(json);
|
||||
String? id;
|
||||
String? shortId;
|
||||
String? title;
|
||||
DateTime? createdAt;
|
||||
String? authorName;
|
||||
String? message;
|
||||
GitlabCommit();
|
||||
factory GitlabCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabDiff {
|
||||
String? diff;
|
||||
String? newPath;
|
||||
String? oldPath;
|
||||
GitlabDiff();
|
||||
factory GitlabDiff.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabDiffFromJson(json);
|
||||
String? diff;
|
||||
String? newPath;
|
||||
String? oldPath;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabIssue {
|
||||
GitlabIssue();
|
||||
factory GitlabIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabIssueFromJson(json);
|
||||
String? title;
|
||||
int? iid;
|
||||
int? projectId;
|
||||
|
@ -197,25 +200,22 @@ class GitlabIssue {
|
|||
int? userNotesCount;
|
||||
DateTime? updatedAt;
|
||||
List<String>? labels;
|
||||
GitlabIssue();
|
||||
factory GitlabIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabStarrer {
|
||||
DateTime? starredSince;
|
||||
GitlabUser? user;
|
||||
GitlabStarrer();
|
||||
factory GitlabStarrer.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabStarrerFromJson(json);
|
||||
DateTime? starredSince;
|
||||
GitlabUser? user;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GitlabBranch {
|
||||
String? name;
|
||||
bool? merged;
|
||||
GitlabBranch();
|
||||
factory GitlabBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GitlabBranchFromJson(json);
|
||||
String? name;
|
||||
bool? merged;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,351 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'gitlab.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GitlabUser _$GitlabUserFromJson(Map<String, dynamic> json) => GitlabUser()
|
||||
..id = json['id'] as int?
|
||||
..username = json['username'] as String?
|
||||
..name = json['name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..bio = json['bio'] as String?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..accessLevel = json['access_level'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GitlabUserToJson(GitlabUser instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'name': instance.name,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'bio': instance.bio,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'access_level': instance.accessLevel,
|
||||
};
|
||||
|
||||
GitlabGroup _$GitlabGroupFromJson(Map<String, dynamic> json) => GitlabGroup()
|
||||
..id = json['id'] as int?
|
||||
..path = json['path'] as String?
|
||||
..name = json['name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..projects = (json['projects'] as List<dynamic>?)
|
||||
?.map((e) => GitlabProject.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
|
||||
Map<String, dynamic> _$GitlabGroupToJson(GitlabGroup instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'path': instance.path,
|
||||
'name': instance.name,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'projects': instance.projects,
|
||||
};
|
||||
|
||||
GitlabTodoProject _$GitlabTodoProjectFromJson(Map<String, dynamic> json) =>
|
||||
GitlabTodoProject()
|
||||
..pathWithNamespace = json['path_with_namespace'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabTodoProjectToJson(GitlabTodoProject instance) =>
|
||||
<String, dynamic>{
|
||||
'path_with_namespace': instance.pathWithNamespace,
|
||||
};
|
||||
|
||||
GitlabTodo _$GitlabTodoFromJson(Map<String, dynamic> json) => GitlabTodo()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..project = json['project'] == null
|
||||
? null
|
||||
: GitlabTodoProject.fromJson(json['project'] as Map<String, dynamic>)
|
||||
..actionName = json['action_name'] as String?
|
||||
..targetType = json['target_type'] as String?
|
||||
..target = json['target'] == null
|
||||
? null
|
||||
: GitlabTodoTarget.fromJson(json['target'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GitlabTodoToJson(GitlabTodo instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'project': instance.project,
|
||||
'action_name': instance.actionName,
|
||||
'target_type': instance.targetType,
|
||||
'target': instance.target,
|
||||
};
|
||||
|
||||
GitlabTodoTarget _$GitlabTodoTargetFromJson(Map<String, dynamic> json) =>
|
||||
GitlabTodoTarget()
|
||||
..iid = json['iid'] as int?
|
||||
..projectId = json['project_id'] as int?
|
||||
..title = json['title'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..description = json['description'] as String?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String);
|
||||
|
||||
Map<String, dynamic> _$GitlabTodoTargetToJson(GitlabTodoTarget instance) =>
|
||||
<String, dynamic>{
|
||||
'iid': instance.iid,
|
||||
'project_id': instance.projectId,
|
||||
'title': instance.title,
|
||||
'author': instance.author,
|
||||
'description': instance.description,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
GitlabIssueNote _$GitlabIssueNoteFromJson(Map<String, dynamic> json) =>
|
||||
GitlabIssueNote()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..body = json['body'] as String?
|
||||
..system = json['system'] as bool?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String);
|
||||
|
||||
Map<String, dynamic> _$GitlabIssueNoteToJson(GitlabIssueNote instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'body': instance.body,
|
||||
'system': instance.system,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
GitlabProject _$GitlabProjectFromJson(Map<String, dynamic> json) =>
|
||||
GitlabProject()
|
||||
..id = json['id'] as int?
|
||||
..name = json['name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..starCount = json['star_count'] as int?
|
||||
..forksCount = json['forks_count'] as int?
|
||||
..visibility = json['visibility'] as String?
|
||||
..readmeUrl = json['readme_url'] as String?
|
||||
..webUrl = json['web_url'] as String?
|
||||
..namespace = json['namespace'] == null
|
||||
? null
|
||||
: GitlabProjectNamespace.fromJson(
|
||||
json['namespace'] as Map<String, dynamic>)
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..issuesEnabled = json['issues_enabled'] as bool?
|
||||
..openIssuesCount = json['open_issues_count'] as int?
|
||||
..mergeRequestsEnabled = json['merge_requests_enabled'] as bool?
|
||||
..statistics = json['statistics'] == null
|
||||
? null
|
||||
: GitlabProjectStatistics.fromJson(
|
||||
json['statistics'] as Map<String, dynamic>)
|
||||
..lastActivityAt = json['last_activity_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['last_activity_at'] as String)
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..defaultBranch = json['default_branch'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectToJson(GitlabProject instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'star_count': instance.starCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'visibility': instance.visibility,
|
||||
'readme_url': instance.readmeUrl,
|
||||
'web_url': instance.webUrl,
|
||||
'namespace': instance.namespace,
|
||||
'owner': instance.owner,
|
||||
'issues_enabled': instance.issuesEnabled,
|
||||
'open_issues_count': instance.openIssuesCount,
|
||||
'merge_requests_enabled': instance.mergeRequestsEnabled,
|
||||
'statistics': instance.statistics,
|
||||
'last_activity_at': instance.lastActivityAt?.toIso8601String(),
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'default_branch': instance.defaultBranch,
|
||||
};
|
||||
|
||||
GitlabProjectBadge _$GitlabProjectBadgeFromJson(Map<String, dynamic> json) =>
|
||||
GitlabProjectBadge()
|
||||
..renderedImageUrl = json['rendered_image_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectBadgeToJson(GitlabProjectBadge instance) =>
|
||||
<String, dynamic>{
|
||||
'rendered_image_url': instance.renderedImageUrl,
|
||||
};
|
||||
|
||||
GitlabProjectStatistics _$GitlabProjectStatisticsFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GitlabProjectStatistics()
|
||||
..commitCount = json['commit_count'] as int?
|
||||
..repositorySize = json['repository_size'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectStatisticsToJson(
|
||||
GitlabProjectStatistics instance) =>
|
||||
<String, dynamic>{
|
||||
'commit_count': instance.commitCount,
|
||||
'repository_size': instance.repositorySize,
|
||||
};
|
||||
|
||||
GitlabProjectNamespace _$GitlabProjectNamespaceFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
GitlabProjectNamespace()
|
||||
..id = json['id'] as int?
|
||||
..name = json['name'] as String?
|
||||
..path = json['path'] as String?
|
||||
..kind = json['kind'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabProjectNamespaceToJson(
|
||||
GitlabProjectNamespace instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'kind': instance.kind,
|
||||
};
|
||||
|
||||
GitlabTreeItem _$GitlabTreeItemFromJson(Map<String, dynamic> json) =>
|
||||
GitlabTreeItem(
|
||||
type: json['type'] as String,
|
||||
path: json['path'] as String,
|
||||
name: json['name'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GitlabTreeItemToJson(GitlabTreeItem instance) =>
|
||||
<String, dynamic>{
|
||||
'type': instance.type,
|
||||
'path': instance.path,
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GitlabBlob _$GitlabBlobFromJson(Map<String, dynamic> json) =>
|
||||
GitlabBlob()..content = json['content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabBlobToJson(GitlabBlob instance) =>
|
||||
<String, dynamic>{
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GitlabEvent _$GitlabEventFromJson(Map<String, dynamic> json) => GitlabEvent()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..actionName = json['action_name'] as String?
|
||||
..targetType = json['target_type'] as String?
|
||||
..note = json['note'] == null
|
||||
? null
|
||||
: GitlabEventNote.fromJson(json['note'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GitlabEventToJson(GitlabEvent instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'action_name': instance.actionName,
|
||||
'target_type': instance.targetType,
|
||||
'note': instance.note,
|
||||
};
|
||||
|
||||
GitlabEventNote _$GitlabEventNoteFromJson(Map<String, dynamic> json) =>
|
||||
GitlabEventNote()
|
||||
..body = json['body'] as String?
|
||||
..noteableType = json['noteable_type'] as String?
|
||||
..noteableIid = json['noteable_iid'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GitlabEventNoteToJson(GitlabEventNote instance) =>
|
||||
<String, dynamic>{
|
||||
'body': instance.body,
|
||||
'noteable_type': instance.noteableType,
|
||||
'noteable_iid': instance.noteableIid,
|
||||
};
|
||||
|
||||
GitlabCommit _$GitlabCommitFromJson(Map<String, dynamic> json) => GitlabCommit()
|
||||
..id = json['id'] as String?
|
||||
..shortId = json['short_id'] as String?
|
||||
..title = json['title'] as String?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..authorName = json['author_name'] as String?
|
||||
..message = json['message'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabCommitToJson(GitlabCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'short_id': instance.shortId,
|
||||
'title': instance.title,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'author_name': instance.authorName,
|
||||
'message': instance.message,
|
||||
};
|
||||
|
||||
GitlabDiff _$GitlabDiffFromJson(Map<String, dynamic> json) => GitlabDiff()
|
||||
..diff = json['diff'] as String?
|
||||
..newPath = json['new_path'] as String?
|
||||
..oldPath = json['old_path'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GitlabDiffToJson(GitlabDiff instance) =>
|
||||
<String, dynamic>{
|
||||
'diff': instance.diff,
|
||||
'new_path': instance.newPath,
|
||||
'old_path': instance.oldPath,
|
||||
};
|
||||
|
||||
GitlabIssue _$GitlabIssueFromJson(Map<String, dynamic> json) => GitlabIssue()
|
||||
..title = json['title'] as String?
|
||||
..iid = json['iid'] as int?
|
||||
..projectId = json['project_id'] as int?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..userNotesCount = json['user_notes_count'] as int?
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..labels =
|
||||
(json['labels'] as List<dynamic>?)?.map((e) => e as String).toList();
|
||||
|
||||
Map<String, dynamic> _$GitlabIssueToJson(GitlabIssue instance) =>
|
||||
<String, dynamic>{
|
||||
'title': instance.title,
|
||||
'iid': instance.iid,
|
||||
'project_id': instance.projectId,
|
||||
'author': instance.author,
|
||||
'user_notes_count': instance.userNotesCount,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'labels': instance.labels,
|
||||
};
|
||||
|
||||
GitlabStarrer _$GitlabStarrerFromJson(Map<String, dynamic> json) =>
|
||||
GitlabStarrer()
|
||||
..starredSince = json['starred_since'] == null
|
||||
? null
|
||||
: DateTime.parse(json['starred_since'] as String)
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GitlabUser.fromJson(json['user'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GitlabStarrerToJson(GitlabStarrer instance) =>
|
||||
<String, dynamic>{
|
||||
'starred_since': instance.starredSince?.toIso8601String(),
|
||||
'user': instance.user,
|
||||
};
|
||||
|
||||
GitlabBranch _$GitlabBranchFromJson(Map<String, dynamic> json) => GitlabBranch()
|
||||
..name = json['name'] as String?
|
||||
..merged = json['merged'] as bool?;
|
||||
|
||||
Map<String, dynamic> _$GitlabBranchToJson(GitlabBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'merged': instance.merged,
|
||||
};
|
|
@ -4,18 +4,21 @@ part 'gogs.g.dart';
|
|||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsUser {
|
||||
GogsUser();
|
||||
factory GogsUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsUserFromJson(json);
|
||||
int? id;
|
||||
String? username;
|
||||
String? fullName;
|
||||
String? avatarUrl;
|
||||
String? email;
|
||||
GogsUser();
|
||||
factory GogsUser.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsUserFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsRepository {
|
||||
GogsRepository();
|
||||
factory GogsRepository.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsRepositoryFromJson(json);
|
||||
int? id;
|
||||
String? fullName;
|
||||
bool? private;
|
||||
|
@ -29,13 +32,13 @@ class GogsRepository {
|
|||
int? forksCount;
|
||||
String? website;
|
||||
int? watchersCount;
|
||||
GogsRepository();
|
||||
factory GogsRepository.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsRepositoryFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsOrg {
|
||||
GogsOrg();
|
||||
factory GogsOrg.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsOrgFromJson(json);
|
||||
int? id;
|
||||
String? username;
|
||||
String? fullName;
|
||||
|
@ -43,73 +46,72 @@ class GogsOrg {
|
|||
String? description;
|
||||
String? location;
|
||||
String? website;
|
||||
GogsOrg();
|
||||
factory GogsOrg.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsOrgFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsTree {
|
||||
GogsTree({required this.type, required this.name});
|
||||
factory GogsTree.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsTreeFromJson(json);
|
||||
String type;
|
||||
String name;
|
||||
String? path;
|
||||
int? size;
|
||||
String? downloadUrl;
|
||||
GogsTree({required this.type, required this.name});
|
||||
factory GogsTree.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsTreeFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsBlob extends GogsTree {
|
||||
String? content;
|
||||
GogsBlob({required String type, required String name})
|
||||
: super(name: name, type: type);
|
||||
GogsBlob({required super.type, required super.name});
|
||||
factory GogsBlob.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsBlobFromJson(json);
|
||||
String? content;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsBranch {
|
||||
String? name;
|
||||
GogsBranch();
|
||||
factory GogsBranch.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsBranchFromJson(json);
|
||||
String? name;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommit {
|
||||
GogsCommit();
|
||||
factory GogsCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitFromJson(json);
|
||||
GogsUser? author;
|
||||
GogsCommitDetail? commit;
|
||||
String? sha;
|
||||
String? htmlUrl;
|
||||
GogsCommit();
|
||||
factory GogsCommit.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommitDetail {
|
||||
String? message;
|
||||
GogsCommitAuthor? author;
|
||||
GogsCommitAuthor? committer;
|
||||
GogsCommitDetail();
|
||||
factory GogsCommitDetail.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitDetailFromJson(json);
|
||||
String? message;
|
||||
GogsCommitAuthor? author;
|
||||
GogsCommitAuthor? committer;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsCommitAuthor {
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
GogsCommitAuthor();
|
||||
factory GogsCommitAuthor.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsCommitAuthorFromJson(json);
|
||||
String? name;
|
||||
String? email;
|
||||
DateTime? date;
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsIssue {
|
||||
GogsIssue();
|
||||
factory GogsIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsIssueFromJson(json);
|
||||
int? number;
|
||||
String? state;
|
||||
String? title;
|
||||
|
@ -119,16 +121,13 @@ class GogsIssue {
|
|||
DateTime? createdAt;
|
||||
DateTime? updatedAt;
|
||||
int? comments;
|
||||
GogsIssue();
|
||||
factory GogsIssue.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsIssueFromJson(json);
|
||||
}
|
||||
|
||||
@JsonSerializable(fieldRename: FieldRename.snake)
|
||||
class GogsLabel {
|
||||
String? name;
|
||||
String? color;
|
||||
GogsLabel();
|
||||
factory GogsLabel.fromJson(Map<String, dynamic> json) =>
|
||||
_$GogsLabelFromJson(json);
|
||||
String? name;
|
||||
String? color;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'gogs.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
GogsUser _$GogsUserFromJson(Map<String, dynamic> json) => GogsUser()
|
||||
..id = json['id'] as int?
|
||||
..username = json['username'] as String?
|
||||
..fullName = json['full_name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..email = json['email'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsUserToJson(GogsUser instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'email': instance.email,
|
||||
};
|
||||
|
||||
GogsRepository _$GogsRepositoryFromJson(Map<String, dynamic> json) =>
|
||||
GogsRepository()
|
||||
..id = json['id'] as int?
|
||||
..fullName = json['full_name'] as String?
|
||||
..private = json['private'] as bool?
|
||||
..owner = json['owner'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['owner'] as Map<String, dynamic>)
|
||||
..htmlUrl = json['html_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..defaultBranch = json['default_branch'] as String?
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..starsCount = json['stars_count'] as int?
|
||||
..forksCount = json['forks_count'] as int?
|
||||
..website = json['website'] as String?
|
||||
..watchersCount = json['watchers_count'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GogsRepositoryToJson(GogsRepository instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'full_name': instance.fullName,
|
||||
'private': instance.private,
|
||||
'owner': instance.owner,
|
||||
'html_url': instance.htmlUrl,
|
||||
'description': instance.description,
|
||||
'default_branch': instance.defaultBranch,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'stars_count': instance.starsCount,
|
||||
'forks_count': instance.forksCount,
|
||||
'website': instance.website,
|
||||
'watchers_count': instance.watchersCount,
|
||||
};
|
||||
|
||||
GogsOrg _$GogsOrgFromJson(Map<String, dynamic> json) => GogsOrg()
|
||||
..id = json['id'] as int?
|
||||
..username = json['username'] as String?
|
||||
..fullName = json['full_name'] as String?
|
||||
..avatarUrl = json['avatar_url'] as String?
|
||||
..description = json['description'] as String?
|
||||
..location = json['location'] as String?
|
||||
..website = json['website'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsOrgToJson(GogsOrg instance) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'username': instance.username,
|
||||
'full_name': instance.fullName,
|
||||
'avatar_url': instance.avatarUrl,
|
||||
'description': instance.description,
|
||||
'location': instance.location,
|
||||
'website': instance.website,
|
||||
};
|
||||
|
||||
GogsTree _$GogsTreeFromJson(Map<String, dynamic> json) => GogsTree(
|
||||
type: json['type'] as String,
|
||||
name: json['name'] as String,
|
||||
)
|
||||
..path = json['path'] as String?
|
||||
..size = json['size'] as int?
|
||||
..downloadUrl = json['download_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsTreeToJson(GogsTree instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
};
|
||||
|
||||
GogsBlob _$GogsBlobFromJson(Map<String, dynamic> json) => GogsBlob(
|
||||
type: json['type'] as String,
|
||||
name: json['name'] as String,
|
||||
)
|
||||
..path = json['path'] as String?
|
||||
..size = json['size'] as int?
|
||||
..downloadUrl = json['download_url'] as String?
|
||||
..content = json['content'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsBlobToJson(GogsBlob instance) => <String, dynamic>{
|
||||
'type': instance.type,
|
||||
'name': instance.name,
|
||||
'path': instance.path,
|
||||
'size': instance.size,
|
||||
'download_url': instance.downloadUrl,
|
||||
'content': instance.content,
|
||||
};
|
||||
|
||||
GogsBranch _$GogsBranchFromJson(Map<String, dynamic> json) =>
|
||||
GogsBranch()..name = json['name'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsBranchToJson(GogsBranch instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
};
|
||||
|
||||
GogsCommit _$GogsCommitFromJson(Map<String, dynamic> json) => GogsCommit()
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..commit = json['commit'] == null
|
||||
? null
|
||||
: GogsCommitDetail.fromJson(json['commit'] as Map<String, dynamic>)
|
||||
..sha = json['sha'] as String?
|
||||
..htmlUrl = json['html_url'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsCommitToJson(GogsCommit instance) =>
|
||||
<String, dynamic>{
|
||||
'author': instance.author,
|
||||
'commit': instance.commit,
|
||||
'sha': instance.sha,
|
||||
'html_url': instance.htmlUrl,
|
||||
};
|
||||
|
||||
GogsCommitDetail _$GogsCommitDetailFromJson(Map<String, dynamic> json) =>
|
||||
GogsCommitDetail()
|
||||
..message = json['message'] as String?
|
||||
..author = json['author'] == null
|
||||
? null
|
||||
: GogsCommitAuthor.fromJson(json['author'] as Map<String, dynamic>)
|
||||
..committer = json['committer'] == null
|
||||
? null
|
||||
: GogsCommitAuthor.fromJson(
|
||||
json['committer'] as Map<String, dynamic>);
|
||||
|
||||
Map<String, dynamic> _$GogsCommitDetailToJson(GogsCommitDetail instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message,
|
||||
'author': instance.author,
|
||||
'committer': instance.committer,
|
||||
};
|
||||
|
||||
GogsCommitAuthor _$GogsCommitAuthorFromJson(Map<String, dynamic> json) =>
|
||||
GogsCommitAuthor()
|
||||
..name = json['name'] as String?
|
||||
..email = json['email'] as String?
|
||||
..date =
|
||||
json['date'] == null ? null : DateTime.parse(json['date'] as String);
|
||||
|
||||
Map<String, dynamic> _$GogsCommitAuthorToJson(GogsCommitAuthor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'email': instance.email,
|
||||
'date': instance.date?.toIso8601String(),
|
||||
};
|
||||
|
||||
GogsIssue _$GogsIssueFromJson(Map<String, dynamic> json) => GogsIssue()
|
||||
..number = json['number'] as int?
|
||||
..state = json['state'] as String?
|
||||
..title = json['title'] as String?
|
||||
..body = json['body'] as String?
|
||||
..user = json['user'] == null
|
||||
? null
|
||||
: GogsUser.fromJson(json['user'] as Map<String, dynamic>)
|
||||
..labels = (json['labels'] as List<dynamic>?)
|
||||
?.map((e) => GogsLabel.fromJson(e as Map<String, dynamic>))
|
||||
.toList()
|
||||
..createdAt = json['created_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['created_at'] as String)
|
||||
..updatedAt = json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String)
|
||||
..comments = json['comments'] as int?;
|
||||
|
||||
Map<String, dynamic> _$GogsIssueToJson(GogsIssue instance) => <String, dynamic>{
|
||||
'number': instance.number,
|
||||
'state': instance.state,
|
||||
'title': instance.title,
|
||||
'body': instance.body,
|
||||
'user': instance.user,
|
||||
'labels': instance.labels,
|
||||
'created_at': instance.createdAt?.toIso8601String(),
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
'comments': instance.comments,
|
||||
};
|
||||
|
||||
GogsLabel _$GogsLabelFromJson(Map<String, dynamic> json) => GogsLabel()
|
||||
..name = json['name'] as String?
|
||||
..color = json['color'] as String?;
|
||||
|
||||
Map<String, dynamic> _$GogsLabelToJson(GogsLabel instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'color': instance.color,
|
||||
};
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
import '../utils/utils.dart';
|
||||
|
||||
class NotificationGroup {
|
||||
NotificationGroup(this.fullName);
|
||||
String? fullName;
|
||||
List<GithubNotificationItem> items = [];
|
||||
|
||||
|
@ -20,8 +20,6 @@ class NotificationGroup {
|
|||
}
|
||||
|
||||
String get key => '_$hashCode';
|
||||
|
||||
NotificationGroup(this.fullName);
|
||||
}
|
||||
|
||||
class NotificationModel with ChangeNotifier {
|
||||
|
|
|
@ -1,23 +1,15 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:fimber/fimber.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
class AppThemeType {
|
||||
static const material = 0;
|
||||
static const cupertino = 1;
|
||||
static const values = [AppThemeType.material, AppThemeType.cupertino];
|
||||
}
|
||||
|
||||
class AppBrightnessType {
|
||||
static const followSystem = 0;
|
||||
static const light = 1;
|
||||
|
@ -36,77 +28,48 @@ class AppMarkdownType {
|
|||
}
|
||||
|
||||
class PickerItem<T> {
|
||||
PickerItem(this.value, {required this.text});
|
||||
final T value;
|
||||
final String? text;
|
||||
PickerItem(this.value, {required this.text});
|
||||
}
|
||||
|
||||
class PickerGroupItem<T> {
|
||||
final T value;
|
||||
final List<PickerItem<T>> items;
|
||||
final Function(T value)? onChange;
|
||||
final Function(T value)? onClose;
|
||||
|
||||
PickerGroupItem({
|
||||
required this.value,
|
||||
required this.items,
|
||||
this.onChange,
|
||||
this.onClose,
|
||||
});
|
||||
final T value;
|
||||
final List<PickerItem<T>> items;
|
||||
final Function(T value)? onChange;
|
||||
final Function(T value)? onClose;
|
||||
}
|
||||
|
||||
class SelectorItem<T> {
|
||||
SelectorItem({required this.value, required this.text});
|
||||
T value;
|
||||
String text;
|
||||
SelectorItem({required this.value, required this.text});
|
||||
}
|
||||
|
||||
// No animation. For replacing route
|
||||
// TODO: Go back
|
||||
class StaticRoute extends PageRouteBuilder {
|
||||
final WidgetBuilder? builder;
|
||||
StaticRoute({this.builder})
|
||||
: super(
|
||||
pageBuilder: (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
pageBuilder: (context, animation, secondaryAnimation) {
|
||||
return builder!(context);
|
||||
},
|
||||
transitionsBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||
return child;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
class Palette {
|
||||
final Color primary;
|
||||
final Color text;
|
||||
final Color secondaryText;
|
||||
final Color tertiaryText;
|
||||
final Color background;
|
||||
final Color grayBackground;
|
||||
final Color border;
|
||||
|
||||
const Palette({
|
||||
required this.primary,
|
||||
required this.text,
|
||||
required this.secondaryText,
|
||||
required this.tertiaryText,
|
||||
required this.background,
|
||||
required this.grayBackground,
|
||||
required this.border,
|
||||
});
|
||||
final WidgetBuilder? builder;
|
||||
}
|
||||
|
||||
class ThemeModel with ChangeNotifier {
|
||||
String? markdownCss;
|
||||
|
||||
int? _theme;
|
||||
int? get theme => _theme;
|
||||
bool get ready => _theme != null;
|
||||
|
||||
Brightness systemBrightness = Brightness.light;
|
||||
void setSystemBrightness(Brightness v) {
|
||||
if (v != systemBrightness) {
|
||||
|
@ -178,49 +141,11 @@ class ThemeModel with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
final paletteLight = Palette(
|
||||
primary: PrimerColors.blue500,
|
||||
text: Colors.black,
|
||||
secondaryText: Colors.grey.shade800,
|
||||
tertiaryText: Colors.grey.shade600,
|
||||
background: Colors.white,
|
||||
grayBackground: Colors.grey.shade100,
|
||||
border: Colors.grey.shade300,
|
||||
);
|
||||
final paletteDark = Palette(
|
||||
primary: PrimerColors.blue500,
|
||||
text: Colors.grey.shade300,
|
||||
secondaryText: Colors.grey.shade400,
|
||||
tertiaryText: Colors.grey.shade500,
|
||||
background: Colors.black,
|
||||
grayBackground: Colors.grey.shade900,
|
||||
border: Colors.grey.shade700,
|
||||
);
|
||||
|
||||
Palette get palette {
|
||||
switch (brightness) {
|
||||
case Brightness.dark:
|
||||
return paletteDark;
|
||||
case Brightness.light:
|
||||
default:
|
||||
return paletteLight;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
markdownCss = await rootBundle.loadString('images/github-markdown.css');
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final v = prefs.getInt(StorageKeys.iTheme);
|
||||
Fimber.d('read theme: $v');
|
||||
if (AppThemeType.values.contains(v)) {
|
||||
_theme = v;
|
||||
} else if (Platform.isIOS || Platform.isMacOS) {
|
||||
_theme = AppThemeType.cupertino;
|
||||
} else {
|
||||
_theme = AppThemeType.material;
|
||||
}
|
||||
final b = prefs.getInt(StorageKeys.iBrightness);
|
||||
Fimber.d('read brightness: $b');
|
||||
if (AppBrightnessType.values.contains(b)) {
|
||||
|
@ -238,46 +163,6 @@ class ThemeModel with ChangeNotifier {
|
|||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> setTheme(int v) async {
|
||||
_theme = v;
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt(StorageKeys.iTheme, v);
|
||||
Fimber.d('write theme: $v');
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
push(BuildContext context, String url, {bool replace = false}) {
|
||||
// Fimber.d(url);
|
||||
if (url.startsWith('/')) {
|
||||
if (replace) {
|
||||
context.replace(url);
|
||||
} else {
|
||||
context.push(url);
|
||||
}
|
||||
} else {
|
||||
launchStringUrl(url);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> showWarning(BuildContext context, String message) async {
|
||||
showCupertinoDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return CupertinoAlertDialog(
|
||||
title: Text(message),
|
||||
actions: <Widget>[
|
||||
CupertinoDialogAction(
|
||||
child: const Text('OK'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, true);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<bool?> showConfirm(BuildContext context, Widget content) {
|
||||
return showCupertinoDialog(
|
||||
context: context,
|
||||
|
@ -302,37 +187,15 @@ class ThemeModel with ChangeNotifier {
|
|||
);
|
||||
},
|
||||
);
|
||||
// default:
|
||||
// return showDialog(
|
||||
// context: context,
|
||||
// builder: (BuildContext context) {
|
||||
// return AlertDialog(
|
||||
// content: content,
|
||||
// actions: <Widget>[
|
||||
// FlatButton(
|
||||
// child: const Text('CANCEL'),
|
||||
// onPressed: () {
|
||||
// Navigator.pop(context, false);
|
||||
// },
|
||||
// ),
|
||||
// FlatButton(
|
||||
// child: const Text('OK'),
|
||||
// onPressed: () {
|
||||
// Navigator.pop(context, true);
|
||||
// },
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
// },
|
||||
// );
|
||||
}
|
||||
|
||||
static Timer? _debounce;
|
||||
String? _selectedItem;
|
||||
|
||||
showPicker(BuildContext context, PickerGroupItem<String?> groupItem) async {
|
||||
await showCupertinoModalPopup(
|
||||
await AntPopup.show(
|
||||
context: context,
|
||||
closeOnMaskClick: true,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
|
@ -340,10 +203,10 @@ class ThemeModel with ChangeNotifier {
|
|||
Container(
|
||||
alignment: Alignment.bottomCenter,
|
||||
decoration: BoxDecoration(
|
||||
color: palette.background,
|
||||
color: AntTheme.of(context).colorBackground,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: palette.grayBackground,
|
||||
color: AntTheme.of(context).colorBox,
|
||||
width: 0.0,
|
||||
),
|
||||
),
|
||||
|
@ -379,7 +242,7 @@ class ThemeModel with ChangeNotifier {
|
|||
SizedBox(
|
||||
height: 216,
|
||||
child: CupertinoPicker(
|
||||
backgroundColor: palette.background,
|
||||
backgroundColor: AntTheme.of(context).colorBackground,
|
||||
itemExtent: 40,
|
||||
scrollController: FixedExtentScrollController(
|
||||
initialItem: groupItem.items
|
||||
|
@ -400,7 +263,9 @@ class ThemeModel with ChangeNotifier {
|
|||
},
|
||||
children: <Widget>[
|
||||
for (var v in groupItem.items)
|
||||
Text(v.text!, style: TextStyle(color: palette.text)),
|
||||
Text(v.text!,
|
||||
style:
|
||||
TextStyle(color: AntTheme.of(context).colorText)),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
@ -411,33 +276,23 @@ class ThemeModel with ChangeNotifier {
|
|||
}
|
||||
|
||||
showActions(BuildContext context, List<ActionItem> actionItems) async {
|
||||
final value = await showCupertinoModalPopup<int>(
|
||||
await AntActionSheet.show(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CupertinoActionSheet(
|
||||
title: const Text('Actions'),
|
||||
actions: actionItems.asMap().entries.map((entry) {
|
||||
return CupertinoActionSheetAction(
|
||||
isDestructiveAction: entry.value.isDestructiveAction,
|
||||
onPressed: () {
|
||||
Navigator.pop(context, entry.key);
|
||||
},
|
||||
child: Text(entry.value.text!),
|
||||
);
|
||||
}).toList(),
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
isDefaultAction: true,
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
extra: const Text('Actions'),
|
||||
actions: [
|
||||
for (final item in actionItems)
|
||||
AntActionSheetAction(
|
||||
text: Text(
|
||||
item.text!,
|
||||
style: TextStyle(
|
||||
color: item.danger ? AntTheme.of(context).colorDanger : null),
|
||||
),
|
||||
onClick: () {
|
||||
item.onTap?.call(context);
|
||||
},
|
||||
child: const Text('Cancel'),
|
||||
key: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
if (value != null) {
|
||||
actionItems[value].onTap!(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,9 +36,8 @@ import 'package:git_touch/screens/gh_gists_files.dart';
|
|||
import 'package:git_touch/screens/gh_issue.dart';
|
||||
import 'package:git_touch/screens/gh_issue_form.dart';
|
||||
import 'package:git_touch/screens/gh_issues.dart';
|
||||
import 'package:git_touch/screens/gh_meta.dart';
|
||||
import 'package:git_touch/screens/gh_object.dart';
|
||||
import 'package:git_touch/screens/gh_org_repos.dart';
|
||||
import 'package:git_touch/screens/gh_orgs.dart';
|
||||
import 'package:git_touch/screens/gh_pulls.dart';
|
||||
import 'package:git_touch/screens/gh_releases.dart';
|
||||
import 'package:git_touch/screens/gh_repo.dart';
|
||||
|
@ -91,15 +90,21 @@ final router = GoRouter(
|
|||
// common
|
||||
GoRoute(
|
||||
path: 'choose-code-theme',
|
||||
builder: (context, state) => LoginScreen(),
|
||||
builder: (context, state) => CodeThemeScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'login',
|
||||
builder: (context, state) => CodeThemeScreen(),
|
||||
builder: (context, state) => LoginScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'settings',
|
||||
builder: (context, state) => SettingsScreen(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'github-meta',
|
||||
builder: (context, state) => const GhMetaScreen(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// github
|
||||
|
@ -123,16 +128,14 @@ final router = GoRouter(
|
|||
return GhStars(login);
|
||||
case 'repositories':
|
||||
return GhRepos(login);
|
||||
case 'orgrepo':
|
||||
return GhOrgReposScreen(login);
|
||||
case 'organizations':
|
||||
return GhUserOrganizationScreen(login);
|
||||
return GhOrgs(login);
|
||||
case 'gists':
|
||||
return GhGistsScreen(login);
|
||||
case 'events':
|
||||
return GhEventsScreen(login);
|
||||
default:
|
||||
return GhUser(login);
|
||||
return GhUserScreen(login);
|
||||
}
|
||||
},
|
||||
routes: [
|
||||
|
@ -176,7 +179,7 @@ final router = GoRouter(
|
|||
GoRoute(
|
||||
path: 'watchers',
|
||||
builder: (context, state) =>
|
||||
GhWachers(state.params['owner']!, state.params['name']!),
|
||||
GhWatchers(state.params['owner']!, state.params['name']!),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'contributors',
|
||||
|
@ -225,6 +228,13 @@ final router = GoRouter(
|
|||
state.params['name']!,
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'new',
|
||||
builder: (context, state) => GhIssueFormScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: ':number',
|
||||
builder: (context, state) => GhIssueScreen(
|
||||
|
@ -233,13 +243,6 @@ final router = GoRouter(
|
|||
int.parse(state.params['number']!),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'new',
|
||||
builder: (context, state) => GhIssueFormScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
|
@ -248,29 +251,27 @@ final router = GoRouter(
|
|||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'pull/:number',
|
||||
builder: (context, state) => GhIssueScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
int.parse(state.params['number']!),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':number',
|
||||
builder: (context, state) => GhIssueScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
int.parse(state.params['number']!),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'files',
|
||||
builder: (context, state) {
|
||||
return GhFilesScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
int.parse(state.params['number']!),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
path: 'files',
|
||||
builder: (context, state) {
|
||||
return GhFilesScreen(
|
||||
state.params['owner']!,
|
||||
state.params['name']!,
|
||||
int.parse(state.params['number']!),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
@ -351,6 +352,12 @@ final router = GoRouter(
|
|||
prefix: state.queryParams['prefix'],
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'new',
|
||||
builder: (context, state) => GlIssueFormScreen(
|
||||
int.parse(state.params['id']!),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: ':iid',
|
||||
builder: (context, state) => GlIssueScreen(
|
||||
|
@ -358,12 +365,6 @@ final router = GoRouter(
|
|||
int.parse(state.params['iid']!),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'new',
|
||||
builder: (context, state) => GlIssueFormScreen(
|
||||
int.parse(state.params['id']!),
|
||||
),
|
||||
),
|
||||
]),
|
||||
GoRoute(
|
||||
path: 'merge_requests',
|
||||
|
|
|
@ -1,20 +1,16 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class CommonScaffold extends StatelessWidget {
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
final PreferredSizeWidget? bottom;
|
||||
|
||||
const CommonScaffold({
|
||||
required this.title,
|
||||
required this.body,
|
||||
this.action,
|
||||
this.bottom,
|
||||
});
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -22,26 +18,12 @@ class CommonScaffold extends StatelessWidget {
|
|||
// FIXME: A hack to get brightness before MaterialApp been built
|
||||
theme.setSystemBrightness(MediaQuery.of(context).platformBrightness);
|
||||
|
||||
switch (theme.theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: title,
|
||||
trailing: action,
|
||||
),
|
||||
child: SafeArea(child: body),
|
||||
);
|
||||
default:
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: title,
|
||||
actions: [
|
||||
if (action != null) action!,
|
||||
],
|
||||
bottom: bottom,
|
||||
),
|
||||
body: body,
|
||||
);
|
||||
}
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: title,
|
||||
trailing: action,
|
||||
),
|
||||
child: SafeArea(child: body),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,28 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/empty.dart';
|
||||
import 'package:git_touch/widgets/error_reload.dart';
|
||||
import 'package:git_touch/widgets/loading.dart';
|
||||
import 'package:git_touch/widgets/empty.dart';
|
||||
|
||||
export 'package:git_touch/utils/utils.dart';
|
||||
|
||||
// This is a scaffold for infinite scroll screens
|
||||
class ListStatefulScaffold<T, K> extends StatefulWidget {
|
||||
final Widget title;
|
||||
final Widget Function()? actionBuilder;
|
||||
final Widget Function(T payload) itemBuilder;
|
||||
final Future<ListPayload<T, K>> Function(K? cursor) fetch;
|
||||
|
||||
const ListStatefulScaffold({
|
||||
required this.title,
|
||||
required this.fetch,
|
||||
required this.itemBuilder,
|
||||
this.actionBuilder,
|
||||
});
|
||||
final Widget title;
|
||||
final Widget Function()? actionBuilder;
|
||||
final Widget Function(T payload) itemBuilder;
|
||||
final Future<ListPayload<T, K>> Function(K? cursor) fetch;
|
||||
|
||||
@override
|
||||
_ListStatefulScaffoldState<T, K> createState() =>
|
||||
State<ListStatefulScaffold<T, K>> createState() =>
|
||||
_ListStatefulScaffoldState();
|
||||
}
|
||||
|
||||
|
@ -68,7 +66,7 @@ class _ListStatefulScaffoldState<T, K>
|
|||
loading = true;
|
||||
});
|
||||
try {
|
||||
final ListPayload<T, K> p = await widget.fetch(null);
|
||||
final p = await widget.fetch(null);
|
||||
items = p.items.toList();
|
||||
cursor = p.cursor;
|
||||
hasMore = p.hasMore;
|
||||
|
@ -90,7 +88,7 @@ class _ListStatefulScaffoldState<T, K>
|
|||
loadingMore = true;
|
||||
});
|
||||
try {
|
||||
ListPayload<T, K> p = await widget.fetch(cursor);
|
||||
final p = await widget.fetch(cursor);
|
||||
items.addAll(p.items);
|
||||
cursor = p.cursor;
|
||||
hasMore = p.hasMore;
|
||||
|
@ -106,20 +104,6 @@ class _ListStatefulScaffoldState<T, K>
|
|||
}
|
||||
}
|
||||
|
||||
Widget _buildItem(BuildContext context, int index) {
|
||||
if (index == 2 * items.length) {
|
||||
if (hasMore != false) {
|
||||
return const Loading(more: true);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
} else if (index % 2 == 1) {
|
||||
return CommonStyle.border;
|
||||
} else {
|
||||
return widget.itemBuilder(items[index ~/ 2]);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildCupertinoSliver() {
|
||||
if (error.isNotEmpty) {
|
||||
return SliverToBoxAdapter(
|
||||
|
@ -130,58 +114,35 @@ class _ListStatefulScaffoldState<T, K>
|
|||
} else if (items.isEmpty) {
|
||||
return SliverToBoxAdapter(child: EmptyWidget());
|
||||
} else {
|
||||
return SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
_buildItem,
|
||||
childCount: 2 * items.length + 1,
|
||||
),
|
||||
return AntSliverList(
|
||||
count: items.length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == items.length) {
|
||||
if (hasMore != false) {
|
||||
return const Loading(more: true);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
return widget.itemBuilder(items[index]);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildMaterial() {
|
||||
if (error.isNotEmpty) {
|
||||
return ErrorReload(text: error, onTap: _refresh);
|
||||
} else if (loading && items.isEmpty) {
|
||||
return const Loading(more: false);
|
||||
} else if (items.isEmpty) {
|
||||
return EmptyWidget();
|
||||
} else {
|
||||
return Scrollbar(
|
||||
child: ListView.builder(
|
||||
controller: _controller,
|
||||
itemCount: 2 * items.length + 1,
|
||||
itemBuilder: _buildItem,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return CupertinoScrollbar(
|
||||
child: CustomScrollView(
|
||||
controller: _controller,
|
||||
slivers: [
|
||||
CupertinoSliverRefreshControl(onRefresh: _refresh),
|
||||
_buildCupertinoSliver(),
|
||||
],
|
||||
),
|
||||
);
|
||||
default:
|
||||
return RefreshIndicator(
|
||||
onRefresh: _refresh,
|
||||
child: _buildMaterial(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonScaffold(
|
||||
title: widget.title,
|
||||
body: _buildBody(),
|
||||
body: CupertinoScrollbar(
|
||||
child: CustomScrollView(
|
||||
controller: _controller,
|
||||
slivers: [
|
||||
CupertinoSliverRefreshControl(onRefresh: _refresh),
|
||||
_buildCupertinoSliver(),
|
||||
],
|
||||
),
|
||||
),
|
||||
action: widget.actionBuilder?.call(),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../widgets/loading.dart';
|
||||
import '../widgets/link.dart';
|
||||
import '../widgets/error_reload.dart';
|
||||
import 'package:git_touch/widgets/error_reload.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:git_touch/widgets/loading.dart';
|
||||
|
||||
class LongListPayload<T, K> {
|
||||
T header;
|
||||
int totalCount;
|
||||
String? cursor;
|
||||
List<K> leadingItems;
|
||||
List<K>? trailingItems;
|
||||
|
||||
LongListPayload({
|
||||
required this.header,
|
||||
required this.totalCount,
|
||||
|
@ -21,6 +13,11 @@ class LongListPayload<T, K> {
|
|||
required this.leadingItems,
|
||||
this.trailingItems,
|
||||
});
|
||||
T header;
|
||||
int totalCount;
|
||||
String? cursor;
|
||||
List<K> leadingItems;
|
||||
List<K>? trailingItems;
|
||||
}
|
||||
|
||||
// This is a scaffold for issue and pull request
|
||||
|
@ -28,13 +25,6 @@ class LongListPayload<T, K> {
|
|||
// We should load leading and trailing items at first fetching, and do load more in the middle
|
||||
// e.g. https://github.com/reactjs/rfcs/pull/68
|
||||
class LongListStatefulScaffold<T, K> extends StatefulWidget {
|
||||
final Widget title;
|
||||
final Widget Function(T t)? trailingBuilder;
|
||||
final Widget Function(T t) headerBuilder;
|
||||
final Widget Function(K k) itemBuilder;
|
||||
final Future<LongListPayload<T, K>> Function() onRefresh;
|
||||
final Future<LongListPayload<T, K>> Function(String? cursor) onLoadMore;
|
||||
|
||||
const LongListStatefulScaffold({
|
||||
required this.title,
|
||||
this.trailingBuilder,
|
||||
|
@ -43,9 +33,15 @@ class LongListStatefulScaffold<T, K> extends StatefulWidget {
|
|||
required this.onRefresh,
|
||||
required this.onLoadMore,
|
||||
});
|
||||
final Widget title;
|
||||
final Widget Function(T t)? trailingBuilder;
|
||||
final Widget Function(T t) headerBuilder;
|
||||
final Widget Function(K k) itemBuilder;
|
||||
final Future<LongListPayload<T, K>> Function() onRefresh;
|
||||
final Future<LongListPayload<T, K>> Function(String? cursor) onLoadMore;
|
||||
|
||||
@override
|
||||
_LongListStatefulScaffoldState<T, K> createState() =>
|
||||
State<LongListStatefulScaffold<T, K>> createState() =>
|
||||
_LongListStatefulScaffoldState();
|
||||
}
|
||||
|
||||
|
@ -89,7 +85,7 @@ class _LongListStatefulScaffoldState<T, K>
|
|||
loadingMore = true;
|
||||
});
|
||||
try {
|
||||
LongListPayload<T?, K> p = await widget.onLoadMore(payload!.cursor);
|
||||
final LongListPayload<T?, K> p = await widget.onLoadMore(payload!.cursor);
|
||||
payload!.totalCount = p.totalCount;
|
||||
payload!.cursor = p.cursor;
|
||||
payload!.leadingItems.addAll(p.leadingItems);
|
||||
|
@ -103,18 +99,16 @@ class _LongListStatefulScaffoldState<T, K>
|
|||
}
|
||||
|
||||
Widget _buildItem(BuildContext context, int index) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
if (index % 2 == 1) {
|
||||
return CommonStyle.border;
|
||||
}
|
||||
|
||||
int realIndex = index ~/ 2;
|
||||
final realIndex = index ~/ 2;
|
||||
|
||||
if (realIndex < payload!.leadingItems.length) {
|
||||
return widget.itemBuilder(payload!.leadingItems[realIndex]);
|
||||
} else if (realIndex == payload!.leadingItems.length) {
|
||||
var count = payload!.totalCount -
|
||||
final count = payload!.totalCount -
|
||||
payload!.leadingItems.length +
|
||||
payload!.trailingItems!.length;
|
||||
return Container(
|
||||
|
@ -125,20 +119,21 @@ class _LongListStatefulScaffoldState<T, K>
|
|||
child: Container(
|
||||
padding: CommonStyle.padding,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: theme.palette.text),
|
||||
border: Border.all(color: AntTheme.of(context).colorText),
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text('$count hidden items',
|
||||
style:
|
||||
TextStyle(color: theme.palette.text, fontSize: 15)),
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context).colorText, fontSize: 15)),
|
||||
const Padding(padding: EdgeInsets.only(top: 4)),
|
||||
loadingMore
|
||||
? const CupertinoActivityIndicator()
|
||||
: Text(
|
||||
'Load more...',
|
||||
style: TextStyle(
|
||||
color: theme.palette.primary, fontSize: 16),
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
fontSize: 16),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -153,7 +148,7 @@ class _LongListStatefulScaffoldState<T, K>
|
|||
}
|
||||
|
||||
int get _itemCount {
|
||||
int count = payload!.leadingItems.length + payload!.trailingItems!.length;
|
||||
var count = payload!.leadingItems.length + payload!.trailingItems!.length;
|
||||
if (payload!.totalCount > count) {
|
||||
count++;
|
||||
}
|
||||
|
@ -177,51 +172,27 @@ class _LongListStatefulScaffoldState<T, K>
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
List<Widget> slivers = [
|
||||
CupertinoSliverRefreshControl(onRefresh: _refresh)
|
||||
];
|
||||
if (payload != null) {
|
||||
slivers.add(
|
||||
SliverToBoxAdapter(child: widget.headerBuilder(payload!.header)),
|
||||
);
|
||||
}
|
||||
slivers.add(_buildSliver());
|
||||
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: widget.title,
|
||||
trailing: payload == null
|
||||
? null
|
||||
: widget.trailingBuilder!(payload!.header),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: CupertinoScrollbar(
|
||||
child: CustomScrollView(slivers: slivers),
|
||||
),
|
||||
),
|
||||
);
|
||||
default:
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: widget.title,
|
||||
actions: payload == null
|
||||
? null
|
||||
: [widget.trailingBuilder!(payload!.header)],
|
||||
),
|
||||
body: RefreshIndicator(
|
||||
onRefresh: _refresh,
|
||||
child: Scrollbar(
|
||||
child: CustomScrollView(slivers: [
|
||||
if (payload != null)
|
||||
SliverToBoxAdapter(
|
||||
child: widget.headerBuilder(payload!.header)),
|
||||
_buildSliver(),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
final slivers = <Widget>[
|
||||
CupertinoSliverRefreshControl(onRefresh: _refresh)
|
||||
];
|
||||
if (payload != null) {
|
||||
slivers.add(
|
||||
SliverToBoxAdapter(child: widget.headerBuilder(payload!.header)),
|
||||
);
|
||||
}
|
||||
slivers.add(_buildSliver());
|
||||
|
||||
return CupertinoPageScaffold(
|
||||
navigationBar: CupertinoNavigationBar(
|
||||
middle: widget.title,
|
||||
trailing:
|
||||
payload == null ? null : widget.trailingBuilder!(payload!.header),
|
||||
),
|
||||
child: SafeArea(
|
||||
child: CupertinoScrollbar(
|
||||
child: CustomScrollView(slivers: slivers),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/scaffolds/utils.dart';
|
||||
|
||||
class RefreshStatefulScaffold<T> extends StatefulWidget {
|
||||
final Widget title;
|
||||
final Widget? Function(T data, void Function(T newData) setData) bodyBuilder;
|
||||
final Future<T> Function() fetch;
|
||||
final Widget? Function(T data, void Function(T newData) setData)?
|
||||
actionBuilder;
|
||||
final Widget? action;
|
||||
final canRefresh;
|
||||
|
||||
const RefreshStatefulScaffold({
|
||||
required this.title,
|
||||
required this.bodyBuilder,
|
||||
|
@ -20,9 +12,16 @@ class RefreshStatefulScaffold<T> extends StatefulWidget {
|
|||
this.action,
|
||||
this.canRefresh = true,
|
||||
}) : assert(actionBuilder == null || action == null);
|
||||
final Widget title;
|
||||
final Widget? Function(T data, void Function(T newData) setData) bodyBuilder;
|
||||
final Future<T> Function() fetch;
|
||||
final Widget? Function(T data, void Function(T newData) setData)?
|
||||
actionBuilder;
|
||||
final Widget? action;
|
||||
final bool canRefresh;
|
||||
|
||||
@override
|
||||
_RefreshStatefulScaffoldState<T> createState() =>
|
||||
State<RefreshStatefulScaffold<T>> createState() =>
|
||||
_RefreshStatefulScaffoldState();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
|
||||
class SingleScaffold extends StatelessWidget {
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
|
||||
const SingleScaffold({
|
||||
required this.title,
|
||||
required this.body,
|
||||
this.action,
|
||||
});
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonScaffold(
|
||||
title: title,
|
||||
body: Scrollbar(child: SingleChildScrollView(child: body)),
|
||||
body: CupertinoScrollbar(child: SingleChildScrollView(child: body)),
|
||||
action: action,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/scaffolds/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class TabScaffold extends StatelessWidget {
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
final void Function() onRefresh;
|
||||
final List<String> tabs;
|
||||
final int activeTab;
|
||||
final Function(int index) onTabSwitch;
|
||||
|
||||
const TabScaffold({
|
||||
required this.title,
|
||||
required this.body,
|
||||
|
@ -23,57 +12,41 @@ class TabScaffold extends StatelessWidget {
|
|||
required this.activeTab,
|
||||
required this.onTabSwitch,
|
||||
});
|
||||
|
||||
Widget _buildTitle(BuildContext context) {
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return DefaultTextStyle(
|
||||
style: DefaultTextStyle.of(context).style.copyWith(fontSize: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoSlidingSegmentedControl<int>(
|
||||
groupValue: activeTab,
|
||||
onValueChanged: (v) {
|
||||
if (v == null) return;
|
||||
onTabSwitch(v);
|
||||
},
|
||||
children: tabs.asMap().map((key, text) => MapEntry(
|
||||
key,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(text),
|
||||
))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
default:
|
||||
return title;
|
||||
}
|
||||
}
|
||||
final Widget title;
|
||||
final Widget body;
|
||||
final Widget? action;
|
||||
final void Function() onRefresh;
|
||||
final List<String> tabs;
|
||||
final int activeTab;
|
||||
final Function(int index) onTabSwitch;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scaffold = CommonScaffold(
|
||||
title: _buildTitle(context),
|
||||
return CommonScaffold(
|
||||
title: DefaultTextStyle(
|
||||
style: DefaultTextStyle.of(context).style.copyWith(fontSize: 14),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoSlidingSegmentedControl<int>(
|
||||
groupValue: activeTab,
|
||||
onValueChanged: (v) {
|
||||
if (v == null) return;
|
||||
onTabSwitch(v);
|
||||
},
|
||||
children: tabs.asMap().map((key, text) => MapEntry(
|
||||
key,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(text),
|
||||
))),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: RefreshWrapper(body: body, onRefresh: onRefresh),
|
||||
// action: action, // TODO:
|
||||
bottom: TabBar(
|
||||
onTap: onTabSwitch,
|
||||
tabs: tabs.map((text) => Tab(text: text.toUpperCase())).toList(),
|
||||
),
|
||||
);
|
||||
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return scaffold;
|
||||
default:
|
||||
return DefaultTabController(
|
||||
length: tabs.length,
|
||||
child: scaffold,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/scaffolds/tab.dart';
|
||||
import 'package:git_touch/scaffolds/utils.dart';
|
||||
|
||||
class TabStatefulScaffold<T> extends StatefulWidget {
|
||||
final Widget title;
|
||||
final Widget Function(T payload, int activeTab) bodyBuilder;
|
||||
final Future<T> Function(int activeTab) fetchData;
|
||||
final List<String> tabs;
|
||||
final Widget Function(T payload, void Function() refresh)? actionBuilder;
|
||||
|
||||
const TabStatefulScaffold({
|
||||
required this.title,
|
||||
required this.bodyBuilder,
|
||||
|
@ -17,9 +11,14 @@ class TabStatefulScaffold<T> extends StatefulWidget {
|
|||
required this.tabs,
|
||||
this.actionBuilder,
|
||||
});
|
||||
final Widget title;
|
||||
final Widget Function(T payload, int activeTab) bodyBuilder;
|
||||
final Future<T> Function(int activeTab) fetchData;
|
||||
final List<String> tabs;
|
||||
final Widget Function(T payload, void Function() refresh)? actionBuilder;
|
||||
|
||||
@override
|
||||
_TabStatefulScaffoldState<T> createState() => _TabStatefulScaffoldState();
|
||||
State<TabStatefulScaffold<T>> createState() => _TabStatefulScaffoldState();
|
||||
}
|
||||
|
||||
class _TabStatefulScaffoldState<T> extends State<TabStatefulScaffold<T>> {
|
||||
|
|
|
@ -1,55 +1,40 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/widgets/error_reload.dart';
|
||||
import 'package:git_touch/widgets/loading.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class RefreshWrapper extends StatelessWidget {
|
||||
final Widget body;
|
||||
final void Function() onRefresh;
|
||||
|
||||
const RefreshWrapper({
|
||||
required this.onRefresh,
|
||||
required this.body,
|
||||
});
|
||||
final Widget body;
|
||||
final void Function() onRefresh;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return CupertinoScrollbar(
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
CupertinoSliverRefreshControl(
|
||||
onRefresh: onRefresh as Future<void> Function()?),
|
||||
SliverToBoxAdapter(child: body),
|
||||
],
|
||||
),
|
||||
);
|
||||
default:
|
||||
return RefreshIndicator(
|
||||
onRefresh: onRefresh as Future<void> Function(),
|
||||
child: Scrollbar(
|
||||
child: SingleChildScrollView(child: body),
|
||||
),
|
||||
);
|
||||
}
|
||||
return CupertinoScrollbar(
|
||||
child: CustomScrollView(
|
||||
slivers: <Widget>[
|
||||
CupertinoSliverRefreshControl(
|
||||
onRefresh: onRefresh as Future<void> Function()?),
|
||||
SliverToBoxAdapter(child: body),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ErrorLoadingWrapper extends StatelessWidget {
|
||||
final String error;
|
||||
final bool loading;
|
||||
final void Function() reload;
|
||||
final Widget? Function() bodyBuilder;
|
||||
|
||||
const ErrorLoadingWrapper({
|
||||
required this.error,
|
||||
required this.loading,
|
||||
required this.reload,
|
||||
required this.bodyBuilder,
|
||||
});
|
||||
final String error;
|
||||
final bool loading;
|
||||
final void Function() reload;
|
||||
final Widget? Function() bodyBuilder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
// import 'package:flutter/material.dart';
|
||||
// import 'package:git_touch/models/theme.dart';
|
||||
// import 'package:git_touch/scaffolds/single.dart';
|
||||
// import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
// import 'package:git_touch/widgets/table_view.dart';
|
||||
// import 'package:launch_review/launch_review.dart';
|
||||
// import 'package:package_info/package_info.dart';
|
||||
// import 'package:provider/provider.dart';
|
||||
|
||||
// /// Unused
|
||||
// class AboutScreen extends StatefulWidget {
|
||||
// @override
|
||||
// _AboutScreenState createState() => _AboutScreenState();
|
||||
// }
|
||||
|
||||
// class _AboutScreenState extends State<AboutScreen> {
|
||||
// var _version = '';
|
||||
|
||||
// @override
|
||||
// void initState() {
|
||||
// super.initState();
|
||||
// PackageInfo.fromPlatform().then((info) {
|
||||
// setState(() {
|
||||
// _version = info.version;
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// final theme = Provider.of<ThemeModel>(context);
|
||||
// return SingleScaffold(
|
||||
// title: AppBarTitle('About'),
|
||||
// body: Column(
|
||||
// children: <Widget>[
|
||||
// SizedBox(height: 32),
|
||||
// ClipRRect(
|
||||
// borderRadius: BorderRadius.circular(24),
|
||||
// child: Image.asset(
|
||||
// 'images/icon.png',
|
||||
// width: 96,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(height: 12),
|
||||
// Text(
|
||||
// 'GitTouch',
|
||||
// style: TextStyle(fontSize: 20, color: theme.palette.text),
|
||||
// ),
|
||||
// SizedBox(height: 48),
|
||||
// TableView(items: [
|
||||
// TableViewItem(text: Text('Version'), rightWidget: Text(_version)),
|
||||
// TableViewItem(text: Text('Source Code'), url: '/pd4d10/git-touch'),
|
||||
// TableViewItem(
|
||||
// text: Text('Feedback'), url: '/pd4d10/git-touch/issues/new'),
|
||||
// TableViewItem(
|
||||
// text: Text('Rate This App'),
|
||||
// onTap: () {
|
||||
// LaunchReview.launch(
|
||||
// androidAppId: 'io.github.pd4d10.gittouch',
|
||||
// iOSAppId: '1452042346',
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ]),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
// }
|
|
@ -1,23 +1,22 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/commit_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbCommitsScreen extends StatelessWidget {
|
||||
const BbCommitsScreen(this.owner, this.name, this.ref);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String ref;
|
||||
const BbCommitsScreen(this.owner, this.name, this.ref);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return ListStatefulScaffold<BbCommit, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.commits),
|
||||
title: Text(AppLocalizations.of(context)!.commits),
|
||||
fetch: (nextUrl) async {
|
||||
final res = await context.read<AuthModel>().fetchBbWithPage(
|
||||
nextUrl ?? '/repositories/$owner/$name/commits/$ref');
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/repo_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbExploreScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<BbRepo, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.explore),
|
||||
title: Text(AppLocalizations.of(context)!.explore),
|
||||
fetch: (nextUrl) async {
|
||||
final res = await context.read<AuthModel>().fetchBbWithPage(
|
||||
nextUrl ?? '/repositories?role=member&sort=-updated_on');
|
||||
|
@ -24,7 +23,7 @@ class BbExploreScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
return RepositoryItem.bb(payload: v);
|
||||
return RepoItem.bb(payload: v);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:git_touch/widgets/comment_item.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class BbIssueScreen extends StatelessWidget {
|
||||
const BbIssueScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
|
||||
const BbIssueScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<BbIssues, Iterable<BbComment>>>(
|
||||
title: Text("Issue: #$number"),
|
||||
title: Text('Issue: #$number'),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final res = await Future.wait([
|
||||
|
@ -45,7 +45,6 @@ class BbIssueScreen extends StatelessWidget {
|
|||
bodyBuilder: (data, _) {
|
||||
final issue = data.item1;
|
||||
final comments = data.item2;
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Column(children: <Widget>[
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
|
@ -65,7 +64,7 @@ class BbIssueScreen extends StatelessWidget {
|
|||
'$owner / $name',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
@ -73,7 +72,7 @@ class BbIssueScreen extends StatelessWidget {
|
|||
'#$number',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbIssueCommentScreen extends StatefulWidget {
|
||||
const BbIssueCommentScreen(this.owner, this.name, this.number);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
const BbIssueCommentScreen(this.owner, this.name, this.number);
|
||||
|
||||
@override
|
||||
_BbIssueCommentScreenState createState() => _BbIssueCommentScreenState();
|
||||
State<BbIssueCommentScreen> createState() => _BbIssueCommentScreenState();
|
||||
}
|
||||
|
||||
class _BbIssueCommentScreenState extends State<BbIssueCommentScreen> {
|
||||
|
@ -21,7 +21,6 @@ class _BbIssueCommentScreenState extends State<BbIssueCommentScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: const Text('New Comment'),
|
||||
|
@ -30,7 +29,7 @@ class _BbIssueCommentScreenState extends State<BbIssueCommentScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.body,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -40,9 +39,10 @@ class _BbIssueCommentScreenState extends State<BbIssueCommentScreen> {
|
|||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
AntButton(
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
child: const Text('Comment'),
|
||||
onPressed: () async {
|
||||
onClick: () async {
|
||||
await auth.fetchBb(
|
||||
'/repositories/${widget.owner}/${widget.name}/issues/${widget.number}/comments',
|
||||
isPost: true,
|
||||
|
@ -51,8 +51,7 @@ class _BbIssueCommentScreenState extends State<BbIssueCommentScreen> {
|
|||
},
|
||||
);
|
||||
Navigator.pop(context, true);
|
||||
await theme.push(
|
||||
context,
|
||||
await context.pushUrl(
|
||||
'/bitbucket/${widget.owner}/${widget.name}/issues/${widget.number}',
|
||||
replace: true,
|
||||
);
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbIssueFormScreen extends StatefulWidget {
|
||||
const BbIssueFormScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const BbIssueFormScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
_BbIssueFormScreenState createState() => _BbIssueFormScreenState();
|
||||
State<BbIssueFormScreen> createState() => _BbIssueFormScreenState();
|
||||
}
|
||||
|
||||
class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
||||
|
@ -22,7 +22,6 @@ class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: Text(AppLocalizations.of(context)!.submitAnIssue),
|
||||
|
@ -31,7 +30,7 @@ class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.title,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -43,7 +42,7 @@ class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.body,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -53,9 +52,10 @@ class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
|||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
AntButton(
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
child: Text(AppLocalizations.of(context)!.submit),
|
||||
onPressed: () async {
|
||||
onClick: () async {
|
||||
await auth.fetchBbJson(
|
||||
'/repositories/${widget.owner}/${widget.name}/issues',
|
||||
isPost: true,
|
||||
|
@ -64,8 +64,7 @@ class _BbIssueFormScreenState extends State<BbIssueFormScreen> {
|
|||
return BbIssues.fromJson(v);
|
||||
});
|
||||
Navigator.pop(context, true);
|
||||
await theme.push(
|
||||
context,
|
||||
await context.pushUrl(
|
||||
'/bitbucket/${widget.owner}/${widget.name}/issues',
|
||||
replace: true,
|
||||
);
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbIssuesScreen extends StatelessWidget {
|
||||
const BbIssuesScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const BbIssuesScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<BbIssues, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.issues),
|
||||
title: Text(AppLocalizations.of(context)!.issues),
|
||||
actionBuilder: () {
|
||||
return ActionEntry(
|
||||
iconData: Octicons.plus, url: '/bitbucket/$owner/$name/issues/new');
|
||||
|
@ -34,7 +34,7 @@ class BbIssuesScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
int issueNumber =
|
||||
final issueNumber =
|
||||
int.parse(v.issueLink!.replaceFirst(RegExp(r'.*\/'), ''));
|
||||
return IssueItem(
|
||||
avatarUrl: v.reporter!.avatarUrl,
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
import 'dart:convert';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
class BbObjectScreen extends StatelessWidget {
|
||||
const BbObjectScreen(this.owner, this.name, this.ref, {this.path});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String ref;
|
||||
final String? path;
|
||||
const BbObjectScreen(this.owner, this.name, this.ref, {this.path});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
|
||||
return ListStatefulScaffold<dynamic, String?>(
|
||||
title: AppBarTitle(path ?? 'Files'),
|
||||
title: Text(path ?? 'Files'),
|
||||
fetch: (next) async {
|
||||
final res = await auth.fetchBb(
|
||||
next ?? '/repositories/$owner/$name/src/$ref/${path ?? ''}');
|
||||
|
@ -52,7 +53,7 @@ class BbObjectScreen extends StatelessWidget {
|
|||
if (pl is String) {
|
||||
return BlobView(path, text: pl);
|
||||
} else if (pl is BbTree) {
|
||||
return ObjectTreeItem(
|
||||
return createObjectTreeItem(
|
||||
name: p.basename(pl.path),
|
||||
type: pl.type,
|
||||
// size: v.type == 'commit_file' ? v.size : null,
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbPullsScreen extends StatelessWidget {
|
||||
const BbPullsScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const BbPullsScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return ListStatefulScaffold<BbPulls, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.pullRequests),
|
||||
title: Text(AppLocalizations.of(context)!.pullRequests),
|
||||
fetch: (nextUrl) async {
|
||||
final res = await context.read<AuthModel>().fetchBbWithPage(
|
||||
nextUrl ?? '/repositories/$owner/$name/pullrequests');
|
||||
|
@ -29,7 +28,7 @@ class BbPullsScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
int pullNumber =
|
||||
final pullNumber =
|
||||
int.parse(v.pullRequestLink!.replaceFirst(RegExp(r'.*\/'), ''));
|
||||
return IssueItem(
|
||||
avatarUrl: v.author!.avatarUrl,
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/markdown_view.dart';
|
||||
import 'package:git_touch/widgets/repo_header.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbRepoScreen extends StatelessWidget {
|
||||
const BbRepoScreen(this.owner, this.name, {this.branch});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String? branch;
|
||||
const BbRepoScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple3<BbRepo, String?, List<BbBranch>>>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.repository),
|
||||
title: Text(AppLocalizations.of(context)!.repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final r = await auth.fetchBbJson('/repositories/$owner/$name');
|
||||
|
@ -56,36 +57,44 @@ class BbRepoScreen extends StatelessWidget {
|
|||
homepageUrl: p.website,
|
||||
),
|
||||
CommonStyle.border,
|
||||
TableView(
|
||||
items: [
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.code,
|
||||
text: const Text('Code'),
|
||||
rightWidget: Text(filesize(p.size)),
|
||||
url:
|
||||
'/bitbucket/$owner/$name/src/${branch ?? p.mainbranch!.name}',
|
||||
AntList(
|
||||
children: [
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.code),
|
||||
extra: Text(filesize(p.size)),
|
||||
onClick: () {
|
||||
context.push(
|
||||
'/bitbucket/$owner/$name/src/${branch ?? p.mainbranch!.name}');
|
||||
},
|
||||
child: const Text('Code'),
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
text: const Text('Issues'),
|
||||
url: '/bitbucket/$owner/$name/issues',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.issue_opened),
|
||||
child: const Text('Issues'),
|
||||
onClick: () {
|
||||
context.push('/bitbucket/$owner/$name/issues');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_pull_request,
|
||||
text: const Text('Pull requests'),
|
||||
url: '/bitbucket/$owner/$name/pulls',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.git_pull_request),
|
||||
child: const Text('Pull requests'),
|
||||
onClick: () {
|
||||
context.push('/bitbucket/$owner/$name/pulls');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.history,
|
||||
text: const Text('Commits'),
|
||||
url:
|
||||
'/bitbucket/$owner/$name/commits/${branch ?? p.mainbranch!.name}',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.history),
|
||||
child: const Text('Commits'),
|
||||
onClick: () {
|
||||
context.push(
|
||||
'/bitbucket/$owner/$name/commits/${branch ?? p.mainbranch!.name}');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_branch,
|
||||
text: Text(AppLocalizations.of(context)!.branches),
|
||||
rightWidget: Text('${(branch ?? p.mainbranch!.name)!} • ${branches.length}'),
|
||||
onTap: () async {
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.git_branch),
|
||||
extra: Text(
|
||||
'${(branch ?? p.mainbranch!.name)!} • ${branches.length}'),
|
||||
onClick: () async {
|
||||
if (branches.length < 2) return;
|
||||
|
||||
await theme.showPicker(
|
||||
|
@ -97,14 +106,15 @@ class BbRepoScreen extends StatelessWidget {
|
|||
.toList(),
|
||||
onClose: (ref) {
|
||||
if (ref != branch) {
|
||||
theme.push(
|
||||
context, '/bitbucket/$owner/$name?branch=$ref',
|
||||
context.pushUrl(
|
||||
'/bitbucket/$owner/$name?branch=$ref',
|
||||
replace: true);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.branches),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class BbTeamsScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<BbUser, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.teams),
|
||||
title: Text(AppLocalizations.of(context)!.teams),
|
||||
fetch: (nextUrl) async {
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/bitbucket.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/repo_item.dart';
|
||||
import 'package:git_touch/widgets/user_header.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
|
||||
class BbUserScreen extends StatelessWidget {
|
||||
const BbUserScreen(this.login, {this.isTeam = false});
|
||||
final String? login;
|
||||
final bool isTeam;
|
||||
const BbUserScreen(this.login, {this.isTeam = false});
|
||||
bool get isViewer => login == null;
|
||||
|
||||
@override
|
||||
|
@ -59,9 +59,7 @@ class BbUserScreen extends StatelessWidget {
|
|||
),
|
||||
CommonStyle.border,
|
||||
Column(
|
||||
children: <Widget>[
|
||||
for (var v in repos) RepositoryItem.bb(payload: v)
|
||||
],
|
||||
children: <Widget>[for (var v in repos) RepoItem.bb(payload: v)],
|
||||
)
|
||||
],
|
||||
);
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_highlight/flutter_highlight.dart';
|
||||
import 'package:flutter_highlight/theme_map.dart';
|
||||
import 'package:git_touch/models/code.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/single.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class CodeThemeScreen extends StatelessWidget {
|
||||
String _getCode(bool isDark) => '''// ${isDark ? 'Dark' : 'Light'} Mode
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
|
@ -35,23 +34,22 @@ class MyApp extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var codeProvider = Provider.of<CodeModel>(context);
|
||||
var theme = Provider.of<ThemeModel>(context);
|
||||
final codeProvider = Provider.of<CodeModel>(context);
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
return SingleScaffold(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.codeTheme),
|
||||
title: Text(AppLocalizations.of(context)!.codeTheme),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
CommonStyle.verticalGap,
|
||||
TableView(
|
||||
headerText: AppLocalizations.of(context)!.fontStyle,
|
||||
hasIcon: false,
|
||||
items: [
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.fontSize),
|
||||
rightWidget: Text(codeProvider.fontSize.toString()),
|
||||
onTap: () {
|
||||
AntList(
|
||||
mode: AntListMode.card,
|
||||
header: Text(AppLocalizations.of(context)!.fontStyle),
|
||||
children: [
|
||||
AntListItem(
|
||||
extra: Text(codeProvider.fontSize.toString()),
|
||||
onClick: () {
|
||||
theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
|
@ -66,11 +64,11 @@ class MyApp extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.fontSize),
|
||||
),
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.fontFamily),
|
||||
rightWidget: Text(codeProvider.fontFamily),
|
||||
onTap: () {
|
||||
AntListItem(
|
||||
extra: Text(codeProvider.fontFamily),
|
||||
onClick: () {
|
||||
theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
|
@ -78,23 +76,24 @@ class MyApp extends StatelessWidget {
|
|||
items: CodeModel.fontFamilies
|
||||
.map((v) => PickerItem(v, text: v))
|
||||
.toList(),
|
||||
onChange: (String? value) {
|
||||
onChange: (value) {
|
||||
codeProvider.setFontFamily(value!);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.fontFamily),
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
TableView(
|
||||
headerText: AppLocalizations.of(context)!.syntaxHighlighting,
|
||||
items: [
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.light),
|
||||
rightWidget: Text(codeProvider.theme),
|
||||
onTap: () {
|
||||
AntList(
|
||||
mode: AntListMode.card,
|
||||
header: Text(AppLocalizations.of(context)!.syntaxHighlighting),
|
||||
children: [
|
||||
AntListItem(
|
||||
extra: Text(codeProvider.theme),
|
||||
onClick: () {
|
||||
theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
|
@ -108,11 +107,20 @@ class MyApp extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.light),
|
||||
),
|
||||
TableViewItem(
|
||||
text: Text(AppLocalizations.of(context)!.dark),
|
||||
rightWidget: Text(codeProvider.themeDark),
|
||||
onTap: () {
|
||||
AntListItem(
|
||||
child: HighlightView(
|
||||
_getCode(false),
|
||||
language: 'dart',
|
||||
theme: themeMap[codeProvider.theme]!,
|
||||
textStyle: codeProvider.fontStyle,
|
||||
padding: CommonStyle.padding,
|
||||
),
|
||||
),
|
||||
AntListItem(
|
||||
extra: Text(codeProvider.themeDark),
|
||||
onClick: () {
|
||||
theme.showPicker(
|
||||
context,
|
||||
PickerGroupItem(
|
||||
|
@ -126,23 +134,19 @@ class MyApp extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.dark),
|
||||
),
|
||||
AntListItem(
|
||||
child: HighlightView(
|
||||
_getCode(true),
|
||||
language: 'dart',
|
||||
theme: themeMap[codeProvider.themeDark]!,
|
||||
textStyle: codeProvider.fontStyle,
|
||||
padding: CommonStyle.padding,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
HighlightView(
|
||||
_getCode(false),
|
||||
language: 'dart',
|
||||
theme: themeMap[codeProvider.theme]!,
|
||||
textStyle: codeProvider.fontStyle,
|
||||
padding: CommonStyle.padding,
|
||||
),
|
||||
HighlightView(
|
||||
_getCode(true),
|
||||
language: 'dart',
|
||||
theme: themeMap[codeProvider.themeDark]!,
|
||||
textStyle: codeProvider.fontStyle,
|
||||
padding: CommonStyle.padding,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeBlobScreen extends StatelessWidget {
|
||||
const GeBlobScreen(this.owner, this.name, this.sha, this.path);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String sha;
|
||||
final String path;
|
||||
const GeBlobScreen(this.owner, this.name, this.sha, this.path);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.file),
|
||||
title: Text(AppLocalizations.of(context)!.file),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final res = await auth.fetchGitee('/repos/$owner/$name/git/blobs/$sha');
|
||||
return GiteeBlob.fromJson(res).content;
|
||||
},
|
||||
action: const ActionEntry(iconData: Ionicons.cog, url: '/choose-code-theme'),
|
||||
action:
|
||||
const ActionEntry(iconData: Ionicons.cog, url: '/choose-code-theme'),
|
||||
bodyBuilder: (content, _) {
|
||||
return BlobView(path, base64Text: content);
|
||||
},
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
|
@ -7,20 +9,17 @@ import 'package:git_touch/widgets/avatar.dart';
|
|||
import 'package:git_touch/widgets/files_item.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
|
||||
class GeCommitScreen extends StatelessWidget {
|
||||
const GeCommitScreen(this.owner, this.name, this.sha);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String sha;
|
||||
const GeCommitScreen(this.owner, this.name, this.sha);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = context.watch<ThemeModel>();
|
||||
return RefreshStatefulScaffold<GiteeCommit>(
|
||||
title: Text("Commit: ${sha.substring(0, 7)}"),
|
||||
title: Text('Commit: ${sha.substring(0, 7)}'),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final items = await auth.fetchGitee('/repos/$owner/$name/commits/$sha');
|
||||
|
@ -48,7 +47,7 @@ class GeCommitScreen extends StatelessWidget {
|
|||
'$owner / $name',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
@ -56,7 +55,7 @@ class GeCommitScreen extends StatelessWidget {
|
|||
sha.substring(0, 7),
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/commit_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeCommitsScreen extends StatelessWidget {
|
||||
const GeCommitsScreen(this.owner, this.name, {this.branch});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String? branch;
|
||||
const GeCommitsScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeCommit, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.commits),
|
||||
title: Text(AppLocalizations.of(context)!.commits),
|
||||
fetch: (page) async {
|
||||
final res = await context.read<AuthModel>().fetchGiteeWithPage(
|
||||
'/repos/$owner/$name/commits?sha=$branch',
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeContributorsScreen extends StatelessWidget {
|
||||
const GeContributorsScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const GeContributorsScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeContributor, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.contributors),
|
||||
title: Text(AppLocalizations.of(context)!.contributors),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final res = await context
|
||||
|
@ -35,7 +34,6 @@ class GeContributorsScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Row(
|
||||
|
@ -51,7 +49,7 @@ class GeContributorsScreen extends StatelessWidget {
|
|||
Text(
|
||||
v.name!,
|
||||
style: TextStyle(
|
||||
color: theme.palette.primary,
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
|
@ -62,11 +60,10 @@ class GeContributorsScreen extends StatelessWidget {
|
|||
if (v.contributions != null)
|
||||
DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
fontSize: 16,
|
||||
),
|
||||
child: Text(
|
||||
"Contributions: ${v.contributions}"),
|
||||
child: Text('Contributions: ${v.contributions}'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/files_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeFilesScreen extends StatelessWidget {
|
||||
const GeFilesScreen(this.owner, this.name, this.pullNumber);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String pullNumber;
|
||||
const GeFilesScreen(this.owner, this.name, this.pullNumber);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteePullFile, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.files),
|
||||
title: Text(AppLocalizations.of(context)!.files),
|
||||
actionBuilder: () {
|
||||
return ActionButton(
|
||||
title: 'Actions',
|
||||
|
|
|
@ -1,52 +1,50 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:git_touch/widgets/comment_item.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class GeIssueScreen extends StatelessWidget {
|
||||
const GeIssueScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
|
||||
const GeIssueScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
|
||||
List<ActionItem> _buildCommentActionItem(
|
||||
BuildContext context, GiteeComment comment) {
|
||||
final auth = context.read<AuthModel>();
|
||||
final theme = context.read<ThemeModel>();
|
||||
return [
|
||||
ActionItem(
|
||||
iconData: Octicons.pencil,
|
||||
text: 'Edit',
|
||||
onTap: (_) {
|
||||
final uri = Uri(
|
||||
path: '/gitee/$owner/$name/issues/$number/comment',
|
||||
queryParameters: {
|
||||
'body': comment.body,
|
||||
'id': comment.id.toString(),
|
||||
},
|
||||
).toString();
|
||||
theme.push(context, uri);
|
||||
}),
|
||||
text: 'Edit',
|
||||
onTap: (_) {
|
||||
final uri = Uri(
|
||||
path: '/gitee/$owner/$name/issues/$number/comment',
|
||||
queryParameters: {
|
||||
'body': comment.body,
|
||||
'id': comment.id.toString(),
|
||||
},
|
||||
).toString();
|
||||
context.pushUrl(uri);
|
||||
},
|
||||
),
|
||||
ActionItem(
|
||||
iconData: Octicons.trashcan,
|
||||
text: 'Delete',
|
||||
onTap: (_) async {
|
||||
await auth.fetchGitee(
|
||||
'/repos/$owner/$name/issues/comments/${comment.id}',
|
||||
requestType: 'DELETE');
|
||||
await theme.push(context, '/gitee/$owner/$name/issues/$number',
|
||||
await context.pushUrl('/gitee/$owner/$name/issues/$number',
|
||||
replace: true);
|
||||
},
|
||||
),
|
||||
|
@ -56,7 +54,7 @@ class GeIssueScreen extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<Tuple2<GiteeIssue, List<GiteeComment>>>(
|
||||
title: Text("Issue: #$number"),
|
||||
title: Text('Issue: #$number'),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final items = await Future.wait([
|
||||
|
@ -73,7 +71,6 @@ class GeIssueScreen extends StatelessWidget {
|
|||
bodyBuilder: (data, _) {
|
||||
final issue = data.item1;
|
||||
final comments = data.item2;
|
||||
final theme = context.read<ThemeModel>();
|
||||
return Column(children: <Widget>[
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
|
@ -93,7 +90,7 @@ class GeIssueScreen extends StatelessWidget {
|
|||
'$owner / $name',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
@ -101,7 +98,7 @@ class GeIssueScreen extends StatelessWidget {
|
|||
'#$number',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeIssueCommentScreen extends StatefulWidget {
|
||||
const GeIssueCommentScreen(this.owner, this.name, this.number,
|
||||
{this.isPr = false, this.body = '', this.id = ''});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
final String body;
|
||||
final String id;
|
||||
const GeIssueCommentScreen(this.owner, this.name, this.number,
|
||||
{this.isPr = false, this.body = '', this.id = ''});
|
||||
|
||||
@override
|
||||
_GeIssueCommentScreenState createState() => _GeIssueCommentScreenState();
|
||||
State<GeIssueCommentScreen> createState() => _GeIssueCommentScreenState();
|
||||
}
|
||||
|
||||
class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
||||
|
@ -35,7 +35,6 @@ class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: Text(isEdit ? 'Update Comment' : 'New Comment'),
|
||||
|
@ -45,14 +44,15 @@ class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
|||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
controller: _controller,
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.body,
|
||||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
AntButton(
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
child: const Text('Comment'),
|
||||
onPressed: () async {
|
||||
onClick: () async {
|
||||
if (!isEdit) {
|
||||
await auth.fetchGitee(
|
||||
'/repos/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}/comments',
|
||||
|
@ -67,8 +67,7 @@ class _GeIssueCommentScreenState extends State<GeIssueCommentScreen> {
|
|||
);
|
||||
}
|
||||
Navigator.pop(context, '');
|
||||
await theme.push(
|
||||
context,
|
||||
await context.pushUrl(
|
||||
'/gitee/${widget.owner}/${widget.name}/${widget.isPr ? 'pulls' : 'issues'}/${widget.number}',
|
||||
replace: true,
|
||||
);
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeIssueFormScreen extends StatefulWidget {
|
||||
const GeIssueFormScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const GeIssueFormScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
_GeIssueFormScreenState createState() => _GeIssueFormScreenState();
|
||||
State<GeIssueFormScreen> createState() => _GeIssueFormScreenState();
|
||||
}
|
||||
|
||||
class _GeIssueFormScreenState extends State<GeIssueFormScreen> {
|
||||
|
@ -22,7 +22,6 @@ class _GeIssueFormScreenState extends State<GeIssueFormScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final auth = Provider.of<AuthModel>(context);
|
||||
return CommonScaffold(
|
||||
title: Text(AppLocalizations.of(context)!.submitAnIssue),
|
||||
|
@ -31,7 +30,7 @@ class _GeIssueFormScreenState extends State<GeIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.title,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -43,7 +42,7 @@ class _GeIssueFormScreenState extends State<GeIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.body,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -63,8 +62,7 @@ class _GeIssueFormScreenState extends State<GeIssueFormScreen> {
|
|||
).then((v) {
|
||||
return GiteeIssue.fromJson(v);
|
||||
});
|
||||
await theme.push(
|
||||
context,
|
||||
await context.pushUrl(
|
||||
'/gitee/${widget.owner}/${widget.name}/issues/${res.number}',
|
||||
replace: true,
|
||||
);
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/hex_color_tag.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeIssuesScreen extends StatelessWidget {
|
||||
const GeIssuesScreen(this.owner, this.name, {this.isPr = false});
|
||||
final String owner;
|
||||
final String name;
|
||||
final bool isPr;
|
||||
const GeIssuesScreen(this.owner, this.name, {this.isPr = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeIssue, int>(
|
||||
title: AppBarTitle(isPr ? 'Pull Requests' : 'Issues'),
|
||||
title: Text(isPr ? 'Pull Requests' : 'Issues'),
|
||||
fetch: (page) async {
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
|
@ -44,7 +44,7 @@ class GeIssuesScreen extends StatelessWidget {
|
|||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels!)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
HexColorTag(name: label.name!, color: label.color!)
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,52 +1,50 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:git_touch/widgets/comment_item.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class GePullScreen extends StatelessWidget {
|
||||
const GePullScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String number;
|
||||
final bool isPr;
|
||||
|
||||
const GePullScreen(this.owner, this.name, this.number, {this.isPr = false});
|
||||
|
||||
List<ActionItem> _buildCommentActionItem(
|
||||
BuildContext context, GiteeComment comment) {
|
||||
final auth = context.read<AuthModel>();
|
||||
final theme = context.read<ThemeModel>();
|
||||
return [
|
||||
ActionItem(
|
||||
iconData: Octicons.pencil,
|
||||
text: 'Edit',
|
||||
onTap: (_) {
|
||||
final uri = Uri(
|
||||
path: '/gitee/$owner/$name/pulls/$number/comment',
|
||||
queryParameters: {
|
||||
'body': comment.body,
|
||||
'id': comment.id.toString(),
|
||||
},
|
||||
).toString();
|
||||
theme.push(context, uri);
|
||||
}),
|
||||
text: 'Edit',
|
||||
onTap: (_) {
|
||||
final uri = Uri(
|
||||
path: '/gitee/$owner/$name/pulls/$number/comment',
|
||||
queryParameters: {
|
||||
'body': comment.body,
|
||||
'id': comment.id.toString(),
|
||||
},
|
||||
).toString();
|
||||
context.pushUrl(uri);
|
||||
},
|
||||
),
|
||||
ActionItem(
|
||||
iconData: Octicons.trashcan,
|
||||
text: 'Delete',
|
||||
onTap: (_) async {
|
||||
await auth.fetchGitee(
|
||||
'/repos/$owner/$name/pulls/comments/${comment.id}',
|
||||
requestType: 'DELETE');
|
||||
await theme.push(context, '/gitee/$owner/$name/pulls/$number',
|
||||
await context.pushUrl('/gitee/$owner/$name/pulls/$number',
|
||||
replace: true);
|
||||
},
|
||||
),
|
||||
|
@ -58,7 +56,7 @@ class GePullScreen extends StatelessWidget {
|
|||
return RefreshStatefulScaffold<
|
||||
Tuple4<GiteePull, List<GiteeComment>, List<GiteePullFile>,
|
||||
List<GiteeCommit>>>(
|
||||
title: Text("Pull Request: #$number"),
|
||||
title: Text('Pull Request: #$number'),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final items = await Future.wait([
|
||||
|
@ -82,24 +80,24 @@ class GePullScreen extends StatelessWidget {
|
|||
final comments = data.item2;
|
||||
final files = data.item3;
|
||||
final commits = data.item4;
|
||||
final theme = context.read<ThemeModel>();
|
||||
var additions = 0;
|
||||
var deletions = 0;
|
||||
for (var file in files) {
|
||||
for (final file in files) {
|
||||
additions += int.parse(file.additions!);
|
||||
deletions += int.parse(file.deletions!);
|
||||
}
|
||||
return Column(children: <Widget>[
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
LinkWidget(
|
||||
url: '/gitee/$owner/$name',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Column(
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: CommonStyle.padding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
LinkWidget(
|
||||
url: '/gitee/$owner/$name',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
LinkWidget(
|
||||
|
@ -115,7 +113,8 @@ class GePullScreen extends StatelessWidget {
|
|||
'$owner / $name',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context)
|
||||
.colorTextSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
@ -123,7 +122,7 @@ class GePullScreen extends StatelessWidget {
|
|||
'#$number',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -149,7 +148,8 @@ class GePullScreen extends StatelessWidget {
|
|||
LinkWidget(
|
||||
url: '/gitee/$owner/$name/pulls/$number/files',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
|
@ -157,7 +157,8 @@ class GePullScreen extends StatelessWidget {
|
|||
Text(
|
||||
'${files.length} files changed',
|
||||
style: TextStyle(
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context)
|
||||
.colorTextSecondary,
|
||||
fontSize: 17,
|
||||
),
|
||||
),
|
||||
|
@ -165,22 +166,25 @@ class GePullScreen extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Text(
|
||||
'+$additions',
|
||||
style: const TextStyle(
|
||||
color: Colors.green,
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context)
|
||||
.colorSuccess,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
Text(
|
||||
'-$deletions',
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context)
|
||||
.colorDanger,
|
||||
fontSize: 15,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Ionicons.chevron_forward,
|
||||
color: theme.palette.border,
|
||||
color:
|
||||
AntTheme.of(context).colorBorder,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -189,72 +193,74 @@ class GePullScreen extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
CommonStyle.border,
|
||||
ListTileTheme(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
child: ExpansionTile(
|
||||
title: Text(
|
||||
'Commits',
|
||||
style: TextStyle(
|
||||
color: theme.palette.primary,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
children: [
|
||||
for (var commit in commits) ...[
|
||||
LinkWidget(
|
||||
url:
|
||||
'/gitee/$owner/$name/commits/${commit.sha}',
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
commit.sha!.substring(0, 7),
|
||||
style: TextStyle(
|
||||
color: theme.palette.primary,
|
||||
fontSize: 17,
|
||||
fontFamily:
|
||||
CommonStyle.monospace,
|
||||
),
|
||||
),
|
||||
],
|
||||
Column(
|
||||
// title: Text(
|
||||
// 'Commits',
|
||||
// style: TextStyle(
|
||||
// color: AntTheme.of(context).colorPrimary,
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
children: [
|
||||
for (var commit in commits) ...[
|
||||
LinkWidget(
|
||||
url:
|
||||
'/gitee/$owner/$name/commits/${commit.sha}',
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8),
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
commit.sha!.substring(0, 7),
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context)
|
||||
.colorPrimary,
|
||||
fontSize: 17,
|
||||
fontFamily: CommonStyle.monospace,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
)),
|
||||
]),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
CommonStyle.border,
|
||||
],
|
||||
)),
|
||||
Column(
|
||||
children: [
|
||||
for (var comment in comments) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: CommentItem(
|
||||
avatar: Avatar(
|
||||
url: comment.user!.avatarUrl,
|
||||
linkUrl: '/gitee/${comment.user!.login}',
|
||||
),
|
||||
createdAt: DateTime.parse(comment.createdAt!),
|
||||
body: comment.body,
|
||||
login: comment.user!.login,
|
||||
prefix: 'gitee',
|
||||
commentActionItemList:
|
||||
_buildCommentActionItem(context, comment),
|
||||
)),
|
||||
CommonStyle.border,
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
)),
|
||||
Column(children: [
|
||||
for (var comment in comments) ...[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: CommentItem(
|
||||
avatar: Avatar(
|
||||
url: comment.user!.avatarUrl,
|
||||
linkUrl: '/gitee/${comment.user!.login}',
|
||||
),
|
||||
createdAt: DateTime.parse(comment.createdAt!),
|
||||
body: comment.body,
|
||||
login: comment.user!.login,
|
||||
prefix: 'gitee',
|
||||
commentActionItemList:
|
||||
_buildCommentActionItem(context, comment),
|
||||
)),
|
||||
CommonStyle.border,
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
]),
|
||||
]);
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/hex_color_tag.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GePullsScreen extends StatelessWidget {
|
||||
const GePullsScreen(this.owner, this.name, {this.isPr = false});
|
||||
final String owner;
|
||||
final String name;
|
||||
final bool isPr;
|
||||
const GePullsScreen(this.owner, this.name, {this.isPr = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteePull, int>(
|
||||
title: AppBarTitle(isPr ? 'Pull Requests' : 'Issues'),
|
||||
title: Text(isPr ? 'Pull Requests' : 'Issues'),
|
||||
fetch: (page) async {
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
|
@ -39,7 +38,7 @@ class GePullsScreen extends StatelessWidget {
|
|||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels!)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
HexColorTag(name: label.name!, color: label.color!)
|
||||
]),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -1,39 +1,41 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/markdown_view.dart';
|
||||
import 'package:git_touch/widgets/mutation_button.dart';
|
||||
import 'package:git_touch/widgets/repo_header.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class StatusPayload {
|
||||
StatusPayload(this.isWatching, this.isStarred);
|
||||
bool isWatching;
|
||||
bool isStarred;
|
||||
StatusPayload(this.isWatching, this.isStarred);
|
||||
}
|
||||
|
||||
class GeRepoScreen extends StatelessWidget {
|
||||
const GeRepoScreen(this.owner, this.name, {this.branch});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String? branch;
|
||||
const GeRepoScreen(this.owner, this.name, {this.branch});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<
|
||||
Tuple4<GiteeRepo, MarkdownViewData, List<GiteeBranch>, StatusPayload>>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.repository),
|
||||
title: Text(AppLocalizations.of(context)!.repository),
|
||||
fetch: () async {
|
||||
final auth = context.read<AuthModel>();
|
||||
final repo = await auth.fetchGitee('/repos/$owner/$name').then((v) {
|
||||
|
@ -41,8 +43,8 @@ class GeRepoScreen extends StatelessWidget {
|
|||
});
|
||||
|
||||
md() => auth.fetchGitee('/repos/$owner/$name/readme').then((v) {
|
||||
return (v['content'] as String?)?.base64ToUtf8 ?? '';
|
||||
});
|
||||
return (v['content'] as String?)?.base64ToUtf8 ?? '';
|
||||
});
|
||||
html() => md().then((v) async {
|
||||
final res = await http.post(
|
||||
Uri.parse('${auth.activeAccount!.domain}/api/v5/markdown'),
|
||||
|
@ -56,14 +58,14 @@ class GeRepoScreen extends StatelessWidget {
|
|||
await auth.fetchGitee('/repos/$owner/$name/branches').then((v) {
|
||||
return [for (var branch in v) GiteeBranch.fromJson(branch)];
|
||||
});
|
||||
bool isStarred = await auth
|
||||
final isStarred = await auth
|
||||
.fetchGitee('/user/starred/$owner/$name', requestType: 'NO CONTENT')
|
||||
.then((v) => v.statusCode == HttpStatus.noContent);
|
||||
bool isWatching = await auth
|
||||
final isWatching = await auth
|
||||
.fetchGitee('/user/subscriptions/$owner/$name',
|
||||
requestType: 'NO CONTENT')
|
||||
.then((v) => v.statusCode == HttpStatus.noContent);
|
||||
StatusPayload statusPayload = StatusPayload(isWatching, isStarred);
|
||||
final statusPayload = StatusPayload(isWatching, isStarred);
|
||||
return Tuple4(repo, readmeData, branches, statusPayload);
|
||||
},
|
||||
bodyBuilder: (t, setData) {
|
||||
|
@ -86,7 +88,7 @@ class GeRepoScreen extends StatelessWidget {
|
|||
active: t.item4.isWatching,
|
||||
text: t.item4.isWatching ? 'Ignore' : 'Watch',
|
||||
onTap: () async {
|
||||
final String watchType =
|
||||
final watchType =
|
||||
t.item4.isWatching ? 'ignoring' : 'watching';
|
||||
await context.read<AuthModel>().fetchGitee(
|
||||
'/user/subscriptions/$owner/$name?watch_type=$watchType',
|
||||
|
@ -114,54 +116,63 @@ class GeRepoScreen extends StatelessWidget {
|
|||
Row(
|
||||
children: <Widget>[
|
||||
EntryItem(
|
||||
count: p.watchersCount,
|
||||
count: p.watchersCount!,
|
||||
text: 'Watchers',
|
||||
url: '/gitee/$owner/$name/watchers',
|
||||
),
|
||||
EntryItem(
|
||||
count: p.stargazersCount,
|
||||
count: p.stargazersCount!,
|
||||
text: 'Stars',
|
||||
url: '/gitee/$owner/$name/stargazers',
|
||||
),
|
||||
EntryItem(
|
||||
count: p.forksCount,
|
||||
count: p.forksCount!,
|
||||
text: 'Forks',
|
||||
url: '/gitee/$owner/$name/forks',
|
||||
),
|
||||
],
|
||||
),
|
||||
CommonStyle.border,
|
||||
TableView(
|
||||
items: [
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.code,
|
||||
text: const Text('Code'),
|
||||
rightWidget: Text(p.license ?? ''),
|
||||
url: '/gitee/$owner/$name/tree/${branch ?? p.defaultBranch}',
|
||||
AntList(
|
||||
children: [
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.code),
|
||||
extra: Text(p.license ?? ''),
|
||||
onClick: () {
|
||||
context.push(
|
||||
'/gitee/$owner/$name/tree/${branch ?? p.defaultBranch}');
|
||||
},
|
||||
child: const Text('Code'),
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.issue_opened,
|
||||
text: const Text('Issues'),
|
||||
rightWidget: Text(numberFormat.format(p.openIssuesCount)),
|
||||
url: '/gitee/$owner/$name/issues',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.issue_opened),
|
||||
extra: Text(numberFormat.format(p.openIssuesCount)),
|
||||
onClick: () {
|
||||
context.push('/gitee/$owner/$name/issues');
|
||||
},
|
||||
child: const Text('Issues'),
|
||||
),
|
||||
if (p.pullRequestsEnabled!)
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_pull_request,
|
||||
text: const Text('Pull requests'),
|
||||
url: '/gitee/$owner/$name/pulls',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.git_pull_request),
|
||||
child: const Text('Pull requests'),
|
||||
onClick: () {
|
||||
context.push('/gitee/$owner/$name/pulls');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.history,
|
||||
text: const Text('Commits'),
|
||||
url:
|
||||
'/gitee/$owner/$name/commits?branch=${branch ?? p.defaultBranch}',
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.history),
|
||||
child: const Text('Commits'),
|
||||
onClick: () {
|
||||
context.push(
|
||||
'/gitee/$owner/$name/commits?branch=${branch ?? p.defaultBranch}');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.git_branch,
|
||||
text: Text(AppLocalizations.of(context)!.branches),
|
||||
rightWidget: Text('${(branch ?? p.defaultBranch)!} • ${branches.length}'),
|
||||
onTap: () async {
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.git_branch),
|
||||
extra: Text(
|
||||
'${(branch ?? p.defaultBranch)!} • ${branches.length}'),
|
||||
onClick: () async {
|
||||
if (branches.length < 2) return;
|
||||
|
||||
await theme.showPicker(
|
||||
|
@ -173,19 +184,22 @@ class GeRepoScreen extends StatelessWidget {
|
|||
.toList(),
|
||||
onClose: (ref) {
|
||||
if (ref != branch) {
|
||||
theme.push(
|
||||
context, '/gitee/$owner/$name?branch=$ref',
|
||||
context.pushUrl('/gitee/$owner/$name?branch=$ref',
|
||||
replace: true);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.branches),
|
||||
),
|
||||
AntListItem(
|
||||
prefix: const Icon(Octicons.organization),
|
||||
child: const Text('Contributors'),
|
||||
onClick: () {
|
||||
context.push('/gitee/$owner/$name/contributors');
|
||||
},
|
||||
),
|
||||
TableViewItem(
|
||||
leftIconData: Octicons.organization,
|
||||
text: const Text('Contributors'),
|
||||
url: '/gitee/$owner/$name/contributors'),
|
||||
],
|
||||
),
|
||||
CommonStyle.verticalGap,
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/repo_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
|
||||
class GeReposScreen extends StatelessWidget {
|
||||
final String api;
|
||||
final String title;
|
||||
|
||||
const GeReposScreen(String owner)
|
||||
: api = '/users/$owner/repos',
|
||||
title = 'Repositories';
|
||||
|
@ -20,11 +16,13 @@ class GeReposScreen extends StatelessWidget {
|
|||
const GeReposScreen.forks(String owner, String name)
|
||||
: api = '/repos/$owner/$name/forks',
|
||||
title = 'Forks';
|
||||
final String api;
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeRepo, int>(
|
||||
title: AppBarTitle(title),
|
||||
title: Text(title),
|
||||
fetch: (page) async {
|
||||
final res =
|
||||
await context.read<AuthModel>().fetchGiteeWithPage(api, page: page);
|
||||
|
@ -35,7 +33,7 @@ class GeReposScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
return RepositoryItem(
|
||||
return RepoItem(
|
||||
owner: v.namespace!.path,
|
||||
avatarUrl: v.owner!.avatarUrl,
|
||||
name: v.path,
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/loading.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/repo_item.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
|
||||
class GeSearchScreen extends StatefulWidget {
|
||||
@override
|
||||
_GeSearchScreenState createState() => _GeSearchScreenState();
|
||||
State<GeSearchScreen> createState() => _GeSearchScreenState();
|
||||
}
|
||||
|
||||
class _GeSearchScreenState extends State<GeSearchScreen> {
|
||||
|
@ -42,7 +41,7 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
Future<void> _query() async {
|
||||
if (_loading || _keyword.isEmpty) return;
|
||||
|
||||
var keyword = _controller!.text;
|
||||
final keyword = _controller!.text;
|
||||
setState(() {
|
||||
_loading = true;
|
||||
});
|
||||
|
@ -71,37 +70,6 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
}
|
||||
}
|
||||
|
||||
Widget _buildInput() {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
switch (Provider.of<ThemeModel>(context).theme) {
|
||||
case AppThemeType.cupertino:
|
||||
return Container(
|
||||
color: theme.palette.background,
|
||||
child: CupertinoTextField(
|
||||
prefix: Row(
|
||||
children: const <Widget>[
|
||||
SizedBox(width: 8),
|
||||
Icon(Octicons.search, size: 20, color: PrimerColors.gray400),
|
||||
],
|
||||
),
|
||||
placeholder: AppLocalizations.of(context)!.search,
|
||||
clearButtonMode: OverlayVisibilityMode.editing,
|
||||
textInputAction: TextInputAction.go,
|
||||
onSubmitted: (_) => _query(),
|
||||
controller: _controller,
|
||||
),
|
||||
);
|
||||
default:
|
||||
return TextField(
|
||||
decoration: InputDecoration.collapsed(
|
||||
hintText: AppLocalizations.of(context)!.search),
|
||||
textInputAction: TextInputAction.go,
|
||||
onSubmitted: (_) => _query(),
|
||||
controller: _controller,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_onTabSwitch(int? index) {
|
||||
setState(() {
|
||||
_activeTab = index;
|
||||
|
@ -116,7 +84,7 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
Widget _buildItem(p) {
|
||||
switch (_activeTab) {
|
||||
case 0:
|
||||
return RepositoryItem(
|
||||
return RepoItem(
|
||||
owner: p.namespace.path,
|
||||
avatarUrl: p.owner.avatarUrl,
|
||||
name: p.path,
|
||||
|
@ -139,7 +107,7 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
author: p.user.login,
|
||||
avatarUrl: p.user.avatarUrl,
|
||||
commentCount: p.comments,
|
||||
subtitle: '#' + p.number,
|
||||
subtitle: '#${p.number}',
|
||||
title: p.title,
|
||||
updatedAt: DateTime.parse(p.updatedAt),
|
||||
url:
|
||||
|
@ -150,29 +118,41 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context).theme;
|
||||
|
||||
final scaffold = CommonScaffold(
|
||||
title: _buildInput(),
|
||||
return CommonScaffold(
|
||||
title: Container(
|
||||
color: AntTheme.of(context).colorBackground,
|
||||
child: CupertinoTextField(
|
||||
prefix: Row(
|
||||
children: const <Widget>[
|
||||
SizedBox(width: 8),
|
||||
Icon(Octicons.search, size: 20, color: PrimerColors.gray400),
|
||||
],
|
||||
),
|
||||
placeholder: AppLocalizations.of(context)!.search,
|
||||
clearButtonMode: OverlayVisibilityMode.editing,
|
||||
textInputAction: TextInputAction.go,
|
||||
onSubmitted: (_) => _query(),
|
||||
controller: _controller,
|
||||
),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
if (theme == AppThemeType.cupertino)
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: CupertinoSlidingSegmentedControl(
|
||||
groupValue: _activeTab,
|
||||
onValueChanged: _onTabSwitch,
|
||||
children: tabs.asMap().map((key, text) => MapEntry(
|
||||
key,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(text, style: const TextStyle(fontSize: 14)),
|
||||
))),
|
||||
),
|
||||
Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
child: CupertinoSlidingSegmentedControl(
|
||||
groupValue: _activeTab,
|
||||
onValueChanged: _onTabSwitch,
|
||||
children: tabs.asMap().map((key, text) => MapEntry(
|
||||
key,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
child: Text(text, style: const TextStyle(fontSize: 14)),
|
||||
))),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_loading)
|
||||
const Loading()
|
||||
else
|
||||
|
@ -180,19 +160,6 @@ class _GeSearchScreenState extends State<GeSearchScreen> {
|
|||
],
|
||||
),
|
||||
),
|
||||
bottom: TabBar(
|
||||
onTap: _onTabSwitch,
|
||||
tabs: tabs.map((text) => Tab(text: text.toUpperCase())).toList(),
|
||||
),
|
||||
);
|
||||
|
||||
if (theme == AppThemeType.material) {
|
||||
return DefaultTabController(
|
||||
length: tabs.length,
|
||||
child: scaffold,
|
||||
);
|
||||
} else {
|
||||
return scaffold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GeTreeScreen extends StatelessWidget {
|
||||
const GeTreeScreen(this.owner, this.name, this.sha);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String sha;
|
||||
const GeTreeScreen(this.owner, this.name, this.sha);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<List<GiteeTreeItem>>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.files),
|
||||
title: Text(AppLocalizations.of(context)!.files),
|
||||
fetch: () async {
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
|
@ -31,24 +30,19 @@ class GeTreeScreen extends StatelessWidget {
|
|||
return items;
|
||||
},
|
||||
bodyBuilder: (data, _) {
|
||||
return TableView(
|
||||
items: [
|
||||
return AntList(
|
||||
children: [
|
||||
for (var item in data)
|
||||
ObjectTreeItem(
|
||||
createObjectTreeItem(
|
||||
type: item.type,
|
||||
name: item.path,
|
||||
size: item.size,
|
||||
downloadUrl: '', // TODO:
|
||||
url: (() {
|
||||
switch (item.type) {
|
||||
case 'tree':
|
||||
return '/gitee/$owner/$name/tree/${item.sha}?path=${item.path.urlencode}';
|
||||
case 'blob':
|
||||
return '/gitee/$owner/$name/blob/${item.sha}?path=${item.path.urlencode}';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
})(),
|
||||
url: item.type == 'tree'
|
||||
? '/gitee/$owner/$name/tree/${item.sha}?path=${item.path.urlencode}'
|
||||
: item.type == 'blob'
|
||||
? '/gitee/$owner/$name/blob/${item.sha}?path=${item.path.urlencode}'
|
||||
: '',
|
||||
)
|
||||
],
|
||||
);
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/entry_item.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:git_touch/widgets/repo_item.dart';
|
||||
import 'package:git_touch/widgets/user_header.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
class GeUserScreen extends StatelessWidget {
|
||||
const GeUserScreen(this.login, {this.isViewer = false});
|
||||
final String login;
|
||||
final bool isViewer;
|
||||
const GeUserScreen(this.login, {this.isViewer = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -33,7 +33,7 @@ class GeUserScreen extends StatelessWidget {
|
|||
[for (var v in res[1]) GiteeRepo.fromJson(v)],
|
||||
);
|
||||
},
|
||||
title: AppBarTitle(isViewer ? 'Me' : login),
|
||||
title: Text(isViewer ? 'Me' : login),
|
||||
action: isViewer
|
||||
? const ActionEntry(
|
||||
iconData: Ionicons.cog,
|
||||
|
@ -65,30 +65,30 @@ class GeUserScreen extends StatelessWidget {
|
|||
CommonStyle.border,
|
||||
Row(children: [
|
||||
EntryItem(
|
||||
count: user.publicRepos,
|
||||
count: user.publicRepos!,
|
||||
text: 'Repositories',
|
||||
url: '/gitee/$login?tab=repositories',
|
||||
),
|
||||
EntryItem(
|
||||
count: user.stared,
|
||||
count: user.stared!,
|
||||
text: 'Stars',
|
||||
url: '/gitee/$login?tab=stars',
|
||||
),
|
||||
EntryItem(
|
||||
count: user.followers,
|
||||
count: user.followers!,
|
||||
text: 'Followers',
|
||||
url: '/gitee/$login?tab=followers',
|
||||
),
|
||||
EntryItem(
|
||||
count: user.following,
|
||||
count: user.following!,
|
||||
text: 'Following',
|
||||
url: '/gitee/$login?tab=following',
|
||||
),
|
||||
]),
|
||||
// TableView(
|
||||
// AntList(
|
||||
// hasIcon: true,
|
||||
// items: [
|
||||
// TableViewItem(
|
||||
// AntListItem(
|
||||
// leftIconData: Octicons.home,
|
||||
// text: Text('Organizations'),
|
||||
// url: '/gitee/$login?tab=organizations',
|
||||
|
@ -99,7 +99,7 @@ class GeUserScreen extends StatelessWidget {
|
|||
Column(
|
||||
children: <Widget>[
|
||||
for (var v in repos)
|
||||
RepositoryItem(
|
||||
RepoItem(
|
||||
owner: v.namespace!.path,
|
||||
avatarUrl: v.owner!.avatarUrl,
|
||||
name: v.path,
|
||||
|
|
|
@ -1,21 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/gitee.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GeUsersScreen extends StatelessWidget {
|
||||
final String api;
|
||||
final String title;
|
||||
|
||||
const GeUsersScreen.followers(String login)
|
||||
: api = '/users/$login/followers',
|
||||
title = 'Followers';
|
||||
const GeUsersScreen.following(String login)
|
||||
: api = '/users/$login/following',
|
||||
title = "Following";
|
||||
title = 'Following';
|
||||
// GeUsersScreen.member(String login)
|
||||
// : api = '/orgs/$login/members',
|
||||
// title = "Members";
|
||||
|
@ -25,11 +21,13 @@ class GeUsersScreen extends StatelessWidget {
|
|||
const GeUsersScreen.watchers(String owner, String repo)
|
||||
: api = '/repos/$owner/$repo/subscribers',
|
||||
title = 'Watchers';
|
||||
final String api;
|
||||
final String title;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GiteeListUser, int>(
|
||||
title: AppBarTitle(title),
|
||||
title: Text(title),
|
||||
fetch: (page) async {
|
||||
final res =
|
||||
await context.read<AuthModel>().fetchGiteeWithPage(api, page: page);
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
import 'package:ferry/ferry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/schema.schema.gql.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/commit_item.dart';
|
||||
import 'package:gql_github/commits.data.gql.dart';
|
||||
import 'package:gql_github/commits.req.gql.dart';
|
||||
import 'package:gql_github/schema.schema.gql.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GhCommits extends StatelessWidget {
|
||||
const GhCommits(this.owner, this.name, {this.branch});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String? branch;
|
||||
const GhCommits(this.owner, this.name, {this.branch});
|
||||
|
||||
Widget _buildStatus(GStatusState? state) {
|
||||
const size = 18.0;
|
||||
switch (state) {
|
||||
case GStatusState.SUCCESS:
|
||||
return const Icon(Octicons.check, color: GithubPalette.open, size: size);
|
||||
return const Icon(Octicons.check,
|
||||
color: GithubPalette.open, size: size);
|
||||
case GStatusState.FAILURE:
|
||||
return const Icon(Octicons.x, color: GithubPalette.closed, size: size);
|
||||
default:
|
||||
|
@ -32,7 +31,7 @@ class GhCommits extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GCommitsRefCommit_history_nodes, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.commits),
|
||||
title: Text(AppLocalizations.of(context)!.commits),
|
||||
fetch: (cursor) async {
|
||||
final req = GCommitsReq((b) {
|
||||
b.vars.owner = owner;
|
||||
|
@ -41,8 +40,8 @@ class GhCommits extends StatelessWidget {
|
|||
b.vars.ref = branch ?? '';
|
||||
b.vars.after = cursor;
|
||||
});
|
||||
final OperationResponse<GCommitsData, GCommitsVars?> res =
|
||||
await context.read<AuthModel>().gqlClient.request(req).first;
|
||||
final res =
|
||||
await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
final ref = res.data!.repository!.defaultBranchRef ??
|
||||
res.data!.repository!.ref!;
|
||||
final history = (ref.target as GCommitsRefCommit).history;
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/files_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/widgets/files_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhComparisonScreen extends StatelessWidget {
|
||||
const GhComparisonScreen(this.owner, this.name, this.before, this.head);
|
||||
final String owner;
|
||||
final String name;
|
||||
final String before;
|
||||
final String head;
|
||||
const GhComparisonScreen(this.owner, this.name, this.before, this.head);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.files),
|
||||
title: Text(AppLocalizations.of(context)!.files),
|
||||
fetch: () async {
|
||||
final res = await context.read<AuthModel>().ghClient.getJSON(
|
||||
'/repos/$owner/$name/compare/$before...$head',
|
||||
|
@ -43,7 +42,7 @@ class GhComparisonScreen extends StatelessWidget {
|
|||
additions: vs.additions,
|
||||
deletions: vs.deletions,
|
||||
status: vs.status,
|
||||
patch: vs.patch ?? "No text to be shown here",
|
||||
patch: vs.patch ?? 'No text to be shown here',
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/contributor_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GhContributorsScreen extends StatelessWidget {
|
||||
const GhContributorsScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const GhContributorsScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GithubContributorItem, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.contributors),
|
||||
title: Text(AppLocalizations.of(context)!.contributors),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final res = await context
|
||||
|
@ -34,7 +33,7 @@ class GhContributorsScreen extends StatelessWidget {
|
|||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
final String? login = v.login;
|
||||
final login = v.login;
|
||||
return ContributorItem(
|
||||
avatarUrl: v.avatarUrl,
|
||||
commits: v.contributions,
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/event_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhEventsScreen extends StatelessWidget {
|
||||
final String login;
|
||||
const GhEventsScreen(this.login);
|
||||
final String login;
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
return ListStatefulScaffold<GithubEvent, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.events),
|
||||
title: Text(AppLocalizations.of(context)!.events),
|
||||
itemBuilder: (payload) => EventItem(payload),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final events = await context.read<AuthModel>().ghClient.getJSON(
|
||||
'/users/$login/events?page=$page&per_page=$PAGE_SIZE',
|
||||
'/users/$login/events?page=$page&per_page=$kPageSize',
|
||||
convert: (dynamic vs) =>
|
||||
[for (var v in vs) GithubEvent.fromJson(v)]);
|
||||
return ListPayload(
|
||||
cursor: page + 1,
|
||||
hasMore: events.length == PAGE_SIZE,
|
||||
hasMore: events.length == kPageSize,
|
||||
items: events,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/files_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhFilesScreen extends StatelessWidget {
|
||||
const GhFilesScreen(this.owner, this.name, this.pullNumber);
|
||||
final String owner;
|
||||
final String name;
|
||||
final int pullNumber;
|
||||
const GhFilesScreen(this.owner, this.name, this.pullNumber);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GithubFilesItem, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.files),
|
||||
title: Text(AppLocalizations.of(context)!.files),
|
||||
actionBuilder: () {
|
||||
return ActionButton(
|
||||
title: 'Actions',
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
|
||||
class GistObjectScreen extends StatelessWidget {
|
||||
const GistObjectScreen(this.login, this.id, this.file,
|
||||
{this.raw, this.content});
|
||||
final String login;
|
||||
final String id;
|
||||
final String file;
|
||||
final String? raw;
|
||||
final String? content;
|
||||
|
||||
const GistObjectScreen(this.login, this.id, this.file, {this.raw, this.content});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CommonScaffold(
|
||||
title: AppBarTitle(file),
|
||||
title: Text(file),
|
||||
action: const ActionEntry(
|
||||
iconData: Ionicons.cog,
|
||||
url: '/choose-code-theme',
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
import 'package:ferry/ferry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/gists_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/gists_item.dart';
|
||||
import 'package:gql_github/gists.data.gql.dart';
|
||||
import 'package:gql_github/gists.req.gql.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhGistsScreen extends StatelessWidget {
|
||||
final String login;
|
||||
const GhGistsScreen(this.login);
|
||||
final String login;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GGistsData_user_gists_nodes, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.gists),
|
||||
title: Text(AppLocalizations.of(context)!.gists),
|
||||
fetch: (page) async {
|
||||
final req = GGistsReq((b) => b
|
||||
..vars.login = login
|
||||
..vars.after = page);
|
||||
final OperationResponse<GGistsData, GGistsVars?> res =
|
||||
await context.read<AuthModel>().gqlClient.request(req).first;
|
||||
final res =
|
||||
await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
final gists = res.data!.user!.gists;
|
||||
return ListPayload(
|
||||
cursor: gists.pageInfo.endCursor,
|
||||
|
|
|
@ -1,52 +1,49 @@
|
|||
import 'package:ferry/ferry.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:gql_github/gist.data.gql.dart';
|
||||
import 'package:gql_github/gist.req.gql.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhGistsFilesScreen extends StatelessWidget {
|
||||
const GhGistsFilesScreen(this.login, this.id);
|
||||
final String id;
|
||||
final String login;
|
||||
const GhGistsFilesScreen(this.login, this.id);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<GGistData_user_gist?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.files),
|
||||
title: Text(AppLocalizations.of(context)!.files),
|
||||
fetch: () async {
|
||||
final req = GGistReq((b) => b
|
||||
..vars.login = login
|
||||
..vars.name = id);
|
||||
final OperationResponse<GGistData, GGistVars?> res =
|
||||
await context.read<AuthModel>().gqlClient.request(req).first;
|
||||
final res =
|
||||
await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
final gist = res.data!.user!.gist;
|
||||
return gist;
|
||||
},
|
||||
bodyBuilder: (payload, _) {
|
||||
return TableView(
|
||||
items: payload!.files!.map((v) {
|
||||
return AntList(
|
||||
children: payload!.files!.map((v) {
|
||||
final uri = Uri(
|
||||
path: '/github/$login/gists/$id/${v.name}',
|
||||
queryParameters: {
|
||||
'content': v.text,
|
||||
},
|
||||
).toString();
|
||||
return ObjectTreeItem(
|
||||
return createObjectTreeItem(
|
||||
url: uri,
|
||||
type: 'file',
|
||||
name: v.name ?? '',
|
||||
downloadUrl: null,
|
||||
size: v.size,
|
||||
);
|
||||
}),
|
||||
}).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
import 'package:ferry/ferry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/long_list.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_button.dart';
|
||||
import 'package:git_touch/widgets/avatar.dart';
|
||||
import 'package:git_touch/widgets/comment_item.dart';
|
||||
import 'package:git_touch/widgets/link.dart';
|
||||
import 'package:git_touch/widgets/timeline_item.dart';
|
||||
import 'package:github/github.dart' as github;
|
||||
import 'package:gql_github/issue.data.gql.dart';
|
||||
import 'package:gql_github/issue.req.gql.dart';
|
||||
import 'package:primer/primer.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:github/github.dart' as github;
|
||||
import '../scaffolds/long_list.dart';
|
||||
import '../widgets/comment_item.dart';
|
||||
|
||||
class GhIssueScreen extends StatelessWidget {
|
||||
const GhIssueScreen(this.owner, this.name, this.number);
|
||||
final String owner;
|
||||
final String name;
|
||||
final int number;
|
||||
const GhIssueScreen(this.owner, this.name, this.number);
|
||||
|
||||
Widget _buildHeader(
|
||||
BuildContext context, {
|
||||
|
@ -30,7 +29,6 @@ class GhIssueScreen extends StatelessWidget {
|
|||
required Widget body,
|
||||
Iterable<Widget> extraWidgets = const [],
|
||||
}) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: <Widget>[
|
||||
|
@ -49,7 +47,7 @@ class GhIssueScreen extends StatelessWidget {
|
|||
'$owner / $name',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
|
@ -57,7 +55,7 @@ class GhIssueScreen extends StatelessWidget {
|
|||
'#$number',
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -94,8 +92,7 @@ class GhIssueScreen extends StatelessWidget {
|
|||
b.vars.number = number;
|
||||
b.vars.cursor = cursor;
|
||||
});
|
||||
OperationResponse<GIssueData, GIssueVars?> res =
|
||||
await context.read<AuthModel>().gqlClient.request(req).first;
|
||||
final res = await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
return res.data!.repository!;
|
||||
}
|
||||
|
||||
|
@ -136,7 +133,6 @@ class GhIssueScreen extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
headerBuilder: (p) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
if (p.issueOrPullRequest!.G__typename == 'Issue') {
|
||||
final issue = p.issueOrPullRequest
|
||||
as GIssueData_repository_issueOrPullRequest__asIssue;
|
||||
|
@ -225,24 +221,24 @@ class GhIssueScreen extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
Text('${pr.changedFiles} files changed',
|
||||
style: TextStyle(
|
||||
color: theme.palette.secondaryText,
|
||||
color: AntTheme.of(context).colorTextSecondary,
|
||||
fontSize: 17,
|
||||
)),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Text('+${pr.additions}',
|
||||
style: const TextStyle(
|
||||
color: Colors.green,
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context).colorSuccess,
|
||||
fontSize: 15,
|
||||
)),
|
||||
const SizedBox(width: 2),
|
||||
Text('-${pr.deletions}',
|
||||
style: const TextStyle(
|
||||
color: Colors.red,
|
||||
style: TextStyle(
|
||||
color: AntTheme.of(context).colorDanger,
|
||||
fontSize: 15,
|
||||
)),
|
||||
Icon(Ionicons.chevron_forward,
|
||||
color: theme.palette.border),
|
||||
color: AntTheme.of(context).colorBorder),
|
||||
],
|
||||
)
|
||||
],
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/common.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GhIssueFormScreen extends StatefulWidget {
|
||||
const GhIssueFormScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const GhIssueFormScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
_GhIssueFormScreenState createState() => _GhIssueFormScreenState();
|
||||
State<GhIssueFormScreen> createState() => _GhIssueFormScreenState();
|
||||
}
|
||||
|
||||
class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
|
||||
|
@ -22,8 +22,6 @@ class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
|
||||
return CommonScaffold(
|
||||
title: Text(AppLocalizations.of(context)!.submitAnIssue),
|
||||
body: Column(
|
||||
|
@ -31,7 +29,7 @@ class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.title,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -43,7 +41,7 @@ class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
|
|||
Padding(
|
||||
padding: CommonStyle.padding,
|
||||
child: CupertinoTextField(
|
||||
style: TextStyle(color: theme.palette.text),
|
||||
style: TextStyle(color: AntTheme.of(context).colorText),
|
||||
placeholder: AppLocalizations.of(context)!.body,
|
||||
onChanged: (v) {
|
||||
setState(() {
|
||||
|
@ -53,17 +51,17 @@ class _GhIssueFormScreenState extends State<GhIssueFormScreen> {
|
|||
maxLines: 10,
|
||||
),
|
||||
),
|
||||
CupertinoButton.filled(
|
||||
AntButton(
|
||||
color: AntTheme.of(context).colorPrimary,
|
||||
child: Text(AppLocalizations.of(context)!.submit),
|
||||
onPressed: () async {
|
||||
onClick: () async {
|
||||
final slug = RepositorySlug(widget.owner, widget.name);
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
.ghClient
|
||||
.issues
|
||||
.create(slug, IssueRequest(title: _title, body: _body));
|
||||
await theme.push(
|
||||
context,
|
||||
await context.pushUrl(
|
||||
'/github/${widget.owner}/${widget.name}/issues/${res.number}',
|
||||
replace: true,
|
||||
);
|
||||
|
|
|
@ -1,26 +1,24 @@
|
|||
import 'package:ferry/ferry.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.data.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.req.gql.dart';
|
||||
import 'package:git_touch/graphql/__generated__/github.var.gql.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/hex_color_tag.dart';
|
||||
import 'package:git_touch/widgets/issue_item.dart';
|
||||
import 'package:git_touch/widgets/label.dart';
|
||||
import 'package:gql_github/issues.data.gql.dart';
|
||||
import 'package:gql_github/issues.req.gql.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GhIssuesScreen extends StatelessWidget {
|
||||
const GhIssuesScreen(this.owner, this.name);
|
||||
final String owner;
|
||||
final String name;
|
||||
const GhIssuesScreen(this.owner, this.name);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GIssuesData_repository_issues_nodes, String?>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.issues),
|
||||
title: Text(AppLocalizations.of(context)!.issues),
|
||||
actionBuilder: () => ActionEntry(
|
||||
iconData: Octicons.plus,
|
||||
url: '/github/$owner/$name/issues/new',
|
||||
|
@ -31,8 +29,8 @@ class GhIssuesScreen extends StatelessWidget {
|
|||
b.vars.name = name;
|
||||
b.vars.cursor = cursor;
|
||||
});
|
||||
final OperationResponse<GIssuesData, GIssuesVars?> res =
|
||||
await context.read<AuthModel>().gqlClient.request(req).first;
|
||||
final res =
|
||||
await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
final issues = res.data!.repository!.issues;
|
||||
return ListPayload(
|
||||
cursor: issues.pageInfo.endCursor,
|
||||
|
@ -52,7 +50,7 @@ class GhIssuesScreen extends StatelessWidget {
|
|||
? null
|
||||
: Wrap(spacing: 4, runSpacing: 4, children: [
|
||||
for (var label in p.labels!.nodes!)
|
||||
MyLabel(name: label.name, cssColor: label.color)
|
||||
HexColorTag(name: label.name, color: label.color)
|
||||
]),
|
||||
url: '/github/$owner/$name/issues/${p.number}',
|
||||
);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:gql_github/meta.data.gql.dart';
|
||||
import 'package:gql_github/meta.req.gql.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhMetaScreen extends StatelessWidget {
|
||||
const GhMetaScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<GMetaData_meta>(
|
||||
title: const Text('Meta'),
|
||||
fetch: () async {
|
||||
final req = GMetaReq();
|
||||
final res =
|
||||
await context.read<AuthModel>().ghGqlClient.request(req).first;
|
||||
return res.data!.meta;
|
||||
},
|
||||
bodyBuilder: (meta, _) {
|
||||
return AntList(
|
||||
children: [
|
||||
AntListItem(
|
||||
extra: Text(meta.gitHubServicesSha),
|
||||
child: const Text('Service SHA'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/widgets/event_item.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhNewsScreen extends StatefulWidget {
|
||||
@override
|
||||
|
@ -21,7 +20,7 @@ class GhNewsScreenState extends State<GhNewsScreen> {
|
|||
Future.microtask(() async {
|
||||
// Check if there are unread notification items.
|
||||
// 1 item is enough since count is not displayed for now.
|
||||
var items = await context
|
||||
final items = await context
|
||||
.read<AuthModel>()
|
||||
.ghClient
|
||||
.getJSON('/notifications?per_page=1');
|
||||
|
@ -35,7 +34,7 @@ class GhNewsScreenState extends State<GhNewsScreen> {
|
|||
@override
|
||||
Widget build(context) {
|
||||
return ListStatefulScaffold<GithubEvent, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.news),
|
||||
title: Text(AppLocalizations.of(context)!.news),
|
||||
itemBuilder: (payload) => EventItem(payload),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
|
@ -43,12 +42,12 @@ class GhNewsScreenState extends State<GhNewsScreen> {
|
|||
final login = auth.activeAccount!.login;
|
||||
|
||||
final events = await auth.ghClient.getJSON(
|
||||
'/users/$login/received_events?page=$page&per_page=$PAGE_SIZE',
|
||||
'/users/$login/received_events?page=$page&per_page=$kPageSize',
|
||||
convert: (dynamic vs) => [for (var v in vs) GithubEvent.fromJson(v)],
|
||||
);
|
||||
return ListPayload(
|
||||
cursor: page + 1,
|
||||
hasMore: events.length == PAGE_SIZE,
|
||||
hasMore: events.length == kPageSize,
|
||||
items: events,
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/theme.dart';
|
||||
import 'package:git_touch/scaffolds/tab_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import '../widgets/notification_item.dart';
|
||||
import '../widgets/list_group.dart';
|
||||
import '../widgets/empty.dart';
|
||||
import '../utils/utils.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
import 'package:git_touch/models/notification.dart';
|
||||
import 'package:git_touch/scaffolds/tab_stateful.dart';
|
||||
import 'package:git_touch/widgets/empty.dart';
|
||||
import 'package:git_touch/widgets/list_group.dart';
|
||||
import 'package:git_touch/widgets/notification_item.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhNotificationScreen extends StatefulWidget {
|
||||
@override
|
||||
|
@ -30,9 +29,9 @@ class GhNotificationScreenState extends State<GhNotificationScreen> {
|
|||
context.read<NotificationModel>().setCount(ns.length);
|
||||
}
|
||||
|
||||
Map<String, NotificationGroup> groupMap = {};
|
||||
final groupMap = <String, NotificationGroup>{};
|
||||
|
||||
for (var item in ns) {
|
||||
for (final item in ns) {
|
||||
final repo = item.repository!.fullName ?? ''; // TODO: nullable
|
||||
if (groupMap[repo] == null) {
|
||||
groupMap[repo] = NotificationGroup(repo);
|
||||
|
@ -56,7 +55,7 @@ class GhNotificationScreenState extends State<GhNotificationScreen> {
|
|||
schema +=
|
||||
'${group.key}: repository(owner: "${group.owner}", name: "${group.name}") {';
|
||||
|
||||
for (var item in group.items) {
|
||||
for (final item in group.items) {
|
||||
switch (item.subject!.type) {
|
||||
case 'Issue':
|
||||
schema += '''
|
||||
|
@ -82,13 +81,13 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
|
|||
if (schema == '{}') return groupMap;
|
||||
|
||||
// Fimber.d(schema);
|
||||
var data = await context.read<AuthModel>().query(schema);
|
||||
final data = await context.read<AuthModel>().query(schema);
|
||||
groupMap.forEach((repo, group) {
|
||||
for (var item in group.items) {
|
||||
var groupData = data[group.key];
|
||||
for (final item in group.items) {
|
||||
final groupData = data[group.key];
|
||||
if (groupData == null) continue;
|
||||
|
||||
var itemData = data[group.key][item.key];
|
||||
final itemData = data[group.key][item.key];
|
||||
if (itemData != null) {
|
||||
item.state = itemData['state'];
|
||||
}
|
||||
|
@ -105,7 +104,6 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
|
|||
MapEntry<String, NotificationGroup> entry,
|
||||
Map<String, NotificationGroup> groupMap,
|
||||
) {
|
||||
final theme = Provider.of<ThemeModel>(context);
|
||||
final group = entry.value;
|
||||
return ListGroup(
|
||||
title: Row(
|
||||
|
@ -116,7 +114,7 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
|
|||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: theme.palette.text,
|
||||
color: AntTheme.of(context).colorText,
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
|
@ -131,7 +129,7 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
|
|||
},
|
||||
child: Icon(
|
||||
Ionicons.checkmark_done,
|
||||
color: theme.palette.tertiaryText,
|
||||
color: AntTheme.of(context).colorWeak,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
|
@ -156,7 +154,7 @@ ${item.key}: pullRequest(number: ${item.subject!.number}) {
|
|||
@override
|
||||
Widget build(context) {
|
||||
return TabStatefulScaffold<Map<String, NotificationGroup>>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.notification),
|
||||
title: Text(AppLocalizations.of(context)!.notification),
|
||||
tabs: [
|
||||
AppLocalizations.of(context)!.unread,
|
||||
AppLocalizations.of(context)!.participating,
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
import 'package:antd_mobile/antd_mobile.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/refresh_stateful.dart';
|
||||
import 'package:git_touch/utils/utils.dart';
|
||||
import 'package:git_touch/widgets/action_entry.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/blob_view.dart';
|
||||
import 'package:git_touch/widgets/object_tree.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/widgets/table_view.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class GhObjectScreen extends StatelessWidget {
|
||||
const GhObjectScreen(this.owner, this.name, this.ref, {this.path, this.raw});
|
||||
final String owner;
|
||||
final String name;
|
||||
final String ref;
|
||||
final String? path;
|
||||
final String? raw;
|
||||
const GhObjectScreen(this.owner, this.name, this.ref, {this.path, this.raw});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return RefreshStatefulScaffold<RepositoryContents>(
|
||||
// canRefresh: !_isImage, // TODO:
|
||||
title: AppBarTitle(path ?? 'Files'),
|
||||
title: Text(path ?? 'Files'),
|
||||
fetch: () async {
|
||||
// Do not request again for images
|
||||
if (path != null &&
|
||||
|
@ -59,8 +59,8 @@ class GhObjectScreen extends StatelessWidget {
|
|||
},
|
||||
bodyBuilder: (data, _) {
|
||||
if (data.isDirectory) {
|
||||
return TableView(
|
||||
items: data.tree!.map((v) {
|
||||
return AntList(
|
||||
children: data.tree!.map((v) {
|
||||
// if (item.type == 'commit') return null;
|
||||
final uri = Uri(
|
||||
path: '/github/$owner/$name/blob/$ref',
|
||||
|
@ -69,14 +69,14 @@ class GhObjectScreen extends StatelessWidget {
|
|||
...(v.downloadUrl == null ? {} : {'raw': v.downloadUrl}),
|
||||
},
|
||||
).toString();
|
||||
return ObjectTreeItem(
|
||||
return createObjectTreeItem(
|
||||
name: v.name ?? '',
|
||||
type: v.type ?? '',
|
||||
url: uri.toString(),
|
||||
downloadUrl: v.downloadUrl,
|
||||
size: v.type == 'file' ? v.size : null,
|
||||
);
|
||||
}),
|
||||
}).toList(),
|
||||
);
|
||||
} else {
|
||||
// TODO: Markdown base path
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/repository_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:github/github.dart';
|
||||
import 'package:timeago/timeago.dart' as timeago;
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
/// There are some restrictions of organization repos with OAuth
|
||||
///
|
||||
/// https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/restricting-access-to-your-organizations-data
|
||||
///
|
||||
/// So we use RESTful API here for repos of org
|
||||
class GhOrgReposScreen extends StatelessWidget {
|
||||
final String owner;
|
||||
const GhOrgReposScreen(this.owner);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<Repository, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.repositories),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final rs = await context
|
||||
.read<AuthModel>()
|
||||
.ghClient
|
||||
.getJSON<List, List<Repository>>(
|
||||
'/orgs/$owner/repos?sort=updated&page=$page',
|
||||
convert: (vs) => [for (var v in vs) Repository.fromJson(v)],
|
||||
);
|
||||
return ListPayload(
|
||||
cursor: page + 1,
|
||||
items: rs,
|
||||
hasMore: rs.isNotEmpty, // TODO:
|
||||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
return RepositoryItem.gh(
|
||||
owner: v.owner!.login,
|
||||
avatarUrl: v.owner!.avatarUrl,
|
||||
name: v.name,
|
||||
description: v.description,
|
||||
starCount: v.stargazersCount,
|
||||
forkCount: v.forksCount,
|
||||
primaryLanguageName: v.language,
|
||||
primaryLanguageColor: null,
|
||||
note: 'Updated ${timeago.format(v.updatedAt!)}',
|
||||
isPrivate: v.isPrivate,
|
||||
isFork: v.isFork,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:git_touch/models/github.dart';
|
||||
import 'package:git_touch/scaffolds/list_stateful.dart';
|
||||
import 'package:git_touch/widgets/app_bar_title.dart';
|
||||
import 'package:git_touch/widgets/user_item.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:git_touch/models/auth.dart';
|
||||
import 'package:flutter_gen/gen_l10n/S.dart';
|
||||
|
||||
class GhUserOrganizationScreen extends StatelessWidget {
|
||||
final String login;
|
||||
const GhUserOrganizationScreen(this.login);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListStatefulScaffold<GithubUserOrganizationItem, int>(
|
||||
title: AppBarTitle(AppLocalizations.of(context)!.organizations),
|
||||
fetch: (page) async {
|
||||
page = page ?? 1;
|
||||
final res = await context
|
||||
.read<AuthModel>()
|
||||
.ghClient
|
||||
.getJSON<List, List<GithubUserOrganizationItem>>(
|
||||
'/users/$login/orgs?page=$page',
|
||||
convert: (vs) =>
|
||||
[for (var v in vs) GithubUserOrganizationItem.fromJson(v)],
|
||||
);
|
||||
return ListPayload(
|
||||
cursor: page + 1,
|
||||
items: res,
|
||||
hasMore: res.isNotEmpty,
|
||||
);
|
||||
},
|
||||
itemBuilder: (v) {
|
||||
return UserItem.github(
|
||||
avatarUrl: v.avatarUrl,
|
||||
login: v.login,
|
||||
name: null, // TODO: organization name
|
||||
bio: v.description == null ? null : Text(v.description!),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue