Skip to content
代码片段 群组 项目
提交 da20c5d3 编辑于 作者: ling zhang's avatar ling zhang 提交者: 万友 朱
浏览文件

feat: #191 用户查看projects中的星标页面

上级 9a893761
No related branches found
No related tags found
无相关合并请求
显示
73 个添加32 个删除
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="design-iconfont">
<g transform="translate(-30 -305)" fill="none" fill-rule="evenodd">
<path fill="#F8F8FA" d="M0 0H375V812H0z"/>
<rect fill="#FFF" x="15" y="99" width="345" height="621" rx="4"/>
<g stroke="#66696D" stroke-width="1.5">
<path d="M8 2.75A1.75 1.75 0 1 0 8 6.25A1.75 1.75 0 1 0 8 2.75Z" transform="translate(30 305)"/>
<path d="M12,13 C12,10.790861 10.209139,9 8,9 C5.790861,9 4,10.790861 4,13" transform="translate(30 305)"/>
<path fill="#FFF" d="M3.5 10.75A1.75 1.75 0 1 0 3.5 14.25A1.75 1.75 0 1 0 3.5 10.75Z" transform="translate(30 305)"/>
<path fill="#FFF" d="M12.5 10.75A1.75 1.75 0 1 0 12.5 14.25A1.75 1.75 0 1 0 12.5 10.75Z" transform="translate(30 305)"/>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" class="design-iconfont">
<path d="M14.6627068,24.0971484 L7.56388485,26.6405783 C7.04396417,26.8268602 6.4714739,26.5563925 6.28519203,26.0364718 C6.24302883,25.9187925 6.22330341,25.7942511 6.2270381,25.6693023 L6.45232702,18.1319583 C6.45924787,17.9004123 6.38556683,17.6736453 6.24386839,17.4903886 L1.63126619,11.5249708 C1.29343728,11.0880611 1.37375813,10.4600113 1.81066781,10.1221824 C1.90955834,10.0457179 2.02190874,9.98847255 2.14189621,9.95341314 L9.37995442,7.83850826 C9.60230647,7.7735387 9.79520593,7.63338905 9.92570621,7.44199638 L14.1737833,1.2117355 C14.4849142,0.755428599 15.1070455,0.637740224 15.5633524,0.948871156 C15.6666333,1.01929281 15.7557951,1.10845459 15.8262167,1.2117355 L20.0742938,7.44199638 C20.2047941,7.63338905 20.3976935,7.7735387 20.6200456,7.83850826 L27.8581038,9.95341314 C28.3882222,10.1083097 28.6923996,10.663624 28.5375031,11.1937424 C28.5024437,11.3137298 28.4451983,11.4260802 28.3687338,11.5249708 L23.7561316,17.4903886 C23.6144332,17.6736453 23.5407521,17.9004123 23.547673,18.1319583 L23.7729619,25.6693023 C23.7894622,26.2213405 23.3553229,26.682232 22.8032847,26.6987323 C22.6783358,26.7024669 22.5537945,26.6827415 22.4361152,26.6405783 L15.3372932,24.0971484 C15.1192184,24.0190146 14.8807816,24.0190146 14.6627068,24.0971484 Z" transform="translate(0 1)" stroke="#FC6D26" stroke-width="2" fill="none" fill-rule="evenodd"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="design-iconfont">
<path d="M6.38190803,0.5 C6.74943101,0.5 7.08733676,0.701599442 7.26190355,1.02501802 L7.75745221,1.94311726 C7.77490889,1.97545911 7.80869946,1.99561906 7.84545176,1.99561906 L10.7993448,1.99561906 C11.3516296,1.99561906 11.7993448,2.44333431 11.7993448,2.99561906 L11.799,4.746 L12.3936765,4.74621722 C12.9459613,4.74621722 13.3936765,5.19393247 13.3936765,5.74621722 L13.3921915,5.80069459 L12.6691677,12.4207687 C12.6136638,12.9279195 12.1852823,13.3119757 11.6751032,13.3119757 L2.21865946,13.3119757 C1.70848039,13.3119757 1.28009891,12.9279195 1.22459503,12.4207687 L0.506021727,5.85501016 C0.445937046,5.30600354 0.842286594,4.81223747 1.39129322,4.75215279 L1.50008616,4.74621722 L2.078,4.746 L2.07868624,1.5 C2.07868624,0.94771525 2.52640149,0.5 3.07868624,0.5 L6.38190803,0.5 Z M11.835007,6.24525732 L2.05800695,6.24525732 L2.66600695,11.8112573 L11.227007,11.8112573 L11.835007,6.24525732 Z M6.08300695,1.99925732 L3.57800695,1.99925732 L3.57800695,4.72025732 L10.299007,4.72025732 L10.299007,3.49525732 L7.84545176,3.49561906 C7.30641806,3.49561906 6.80720308,3.22457981 6.51260646,2.78082315 L6.43745893,2.65559023 L6.08300695,1.99925732 Z" transform="translate(1 1)" fill="#66696D" fill-rule="nonzero"/>
</svg>
......@@ -48,6 +48,7 @@ class MessageLookup extends MessageLookupByLibrary {
"no_data": MessageLookupByLibrary.simpleMessage("No data"),
"no_favourite": MessageLookupByLibrary.simpleMessage("No favorites"),
"no_match": MessageLookupByLibrary.simpleMessage("No matches for "),
"no_star": MessageLookupByLibrary.simpleMessage("No star"),
"projects": MessageLookupByLibrary.simpleMessage("Projects"),
"projects_children": MessageLookupByLibrary.simpleMessage("Children"),
"projects_groups": MessageLookupByLibrary.simpleMessage("Groups"),
......
......@@ -48,6 +48,7 @@ class MessageLookup extends MessageLookupByLibrary {
"no_data": MessageLookupByLibrary.simpleMessage("没有数据"),
"no_favourite": MessageLookupByLibrary.simpleMessage("没有星标项目"),
"no_match": MessageLookupByLibrary.simpleMessage("没有匹配到"),
"no_star": MessageLookupByLibrary.simpleMessage("没有星标项目"),
"projects": MessageLookupByLibrary.simpleMessage("项目"),
"projects_children": MessageLookupByLibrary.simpleMessage("子组和项目"),
"projects_groups": MessageLookupByLibrary.simpleMessage("群组"),
......
......@@ -176,6 +176,16 @@ class S {
);
}
/// `No star`
String get no_star {
return Intl.message(
'No star',
name: 'no_star',
desc: '',
args: [],
);
}
/// `Create`
String get create {
return Intl.message(
......
......@@ -12,6 +12,7 @@
"done": "Done",
"version_not_support": "Your current version is not support",
"contact_for_support": "please contact us for support",
"no_star": "No star",
"create": "Create",
"uploading": "Uploading",
"assignees": "Assignees",
......
......@@ -9,6 +9,7 @@
"has_no_data": "没有数据了",
"no_match": "没有匹配到",
"search": "搜索",
"no_star": "没有星标项目",
"done": "完成",
"no_favourite": "没有星标项目",
"create_successfully": "创建成功",
......
......@@ -11,7 +11,7 @@ class GroupAndProject {
GroupAndProject(this.id, this.iid, this.name, this.type, this.relativePath, this.parentId, this.starred);
String get icon => type == SubgroupItemType.project ? 'assets/images/project_icon.png' : 'assets/images/group_icon.png';
String get icon => type == SubgroupItemType.project ? 'assets/images/projects.svg' : 'assets/images/groups.svg';
}
class GroupAndProjectEntity {
......@@ -67,8 +67,8 @@ class GroupAndProjectEntity {
}
static GroupAndProjectEntity restore(Map<String, dynamic> map) {
return GroupAndProjectEntity._internal(
map['id'], map['user_id'], map['iid'], map['name'], map['type'], map['relative_path'], map['parent_id'], map['version'], map['starred'] ?? 0, map['last_activity_at'], map['starred_at']);
return GroupAndProjectEntity._internal(map['id'], map['user_id'], map['iid'], map['name'], map['type'], map['relative_path'], map['parent_id'], map['version'], map['starred'] ?? 0,
map['last_activity_at'] ?? 0, map['starred_at'] ?? 0);
}
static int parseDateTime(String? dateTimeString) {
......@@ -86,6 +86,7 @@ class GroupAndProjectEntity {
name = newValue.name;
relativePath = newValue.relativePath;
version = newValue.version;
lastActivityAt = newValue.lastActivityAt;
}
@override
......
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:jihu_gitlab_app/core/widgets/star.dart';
import 'package:jihu_gitlab_app/modules/projects/group_and_project.dart';
import 'package:jihu_gitlab_app/modules/projects/group_details/subgroup_page.dart';
......@@ -30,11 +31,7 @@ class _GroupAndProjectListTileState extends State<GroupAndProjectListTile> {
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
data.icon,
width: 16,
height: 16,
),
SvgPicture.asset(data.icon, width: 16, height: 16),
const SizedBox(width: 12),
Expanded(
flex: 1,
......
......@@ -54,4 +54,9 @@ class GroupAndProjectRepository {
Future<int> countStarred(int userId) async {
return await DbManager.instance().count(GroupAndProjectEntity.tableName, where: " user_id = ? and starred = 1 ", whereArgs: [userId]);
}
Future<int>? cancelStarredProjectsLessThan(int userId, int version) async {
return DbManager.instance().update(GroupAndProjectEntity.tableName, {"starred": 0, "starred_at": 0, "version": version},
where: " user_id = ? and version < ? and type = ? ", whereArgs: [userId, version, SubgroupItemType.project.name]);
}
}
......@@ -22,16 +22,18 @@ class _ProjectsGroupsPageState extends State<ProjectsGroupsPage> {
@override
Widget build(BuildContext context) {
return Consumer<UserProvider>(builder: (context, userProvider, child) {
if (!UserProvider.authorized) {
_model.clear();
return const UnauthorizedView();
} else if (_model.loadState == LoadState.noItemState) {
_model.init();
_model.loadData();
}
return Padding(padding: const EdgeInsets.all(16), child: groupList());
});
return SafeArea(
child: Consumer<UserProvider>(builder: (context, userProvider, child) {
if (!UserProvider.authorized) {
_model.clear();
return const UnauthorizedView();
} else if (_model.loadState == LoadState.noItemState) {
_model.init();
_model.loadData();
}
return Padding(padding: const EdgeInsets.all(16), child: groupList());
}),
);
}
Widget groupList() {
......
......@@ -23,16 +23,18 @@ class _ProjectsStarredPageState extends State<ProjectsStarredPage> {
@override
Widget build(BuildContext context) {
return Consumer<UserProvider>(builder: (context, _, child) {
if (!UserProvider.authorized) {
_model.clear();
return const UnauthorizedView();
} else if (_model.loadState == LoadState.noItemState) {
_model.config();
_model.loadData();
}
return Padding(padding: const EdgeInsets.all(16), child: _starredListView());
});
return SafeArea(
child: Consumer<UserProvider>(builder: (context, _, child) {
if (!UserProvider.authorized) {
_model.clear();
return const UnauthorizedView();
} else if (_model.loadState == LoadState.noItemState) {
_model.config();
_model.loadData();
}
return Padding(padding: const EdgeInsets.all(16), child: _starredListView());
}),
);
}
Widget _starredListView() {
......@@ -40,7 +42,7 @@ class _ProjectsStarredPageState extends State<ProjectsStarredPage> {
valueListenable: _model.notifier,
builder: (BuildContext context, List<GroupAndProject> data, Widget? child) {
if (_model.loadState == LoadState.successState && data.isEmpty) {
return NoDataView(icon: 'assets/images/no_favorites.png', message: S.current.no_favourite);
return NoDataView(icon: 'assets/images/no_star.svg', message: S.current.no_star);
}
return ClipRRect(
borderRadius: BorderRadius.circular(4.0),
......
......@@ -47,10 +47,12 @@ class ProjectsStarredProvider extends DataProvider<GroupAndProject> {
if (result.hasUpdate) {
var list = result.update.map((e) {
e.left.starred = 1;
e.left.version = version;
return e.left;
}).toList();
await _repository.update(list);
}
await _repository.cancelStarredProjectsLessThan(_userId, version);
}
@visibleForTesting
......
......@@ -50,10 +50,10 @@ void main() {
HttpClient.setInstance(client);
when(client.get<List<dynamic>>('/api/v4/users/9527/starred_projects?page=1&per_page=50')).thenAnswer((_) => Future(() => Response.of<List<dynamic>>(starredProjects)));
GroupAndProjectEntity existsProject = GroupAndProjectEntity.restore({
"id": 78632,
"iid": 44,
"id": 44,
"iid": 78632,
"user_id": 9527,
"parent_id": 59893,
"parent_id": 32052,
"name": "tester-44",
"relative_path": "path_with_namespace_44",
"starred": 1,
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册