ggdgsdbsdbbb / issue_routes.v
204 lines · 192 sloc · 6.36 KB · f37c8784f5fa9d9ec6a444802eb6ec14526843ef
Raw
1module main
2
3import veb
4import validation
5import api
6
7struct ItemWithUser[T] {
8 item T
9 user User
10}
11
12type IssueWithUser = ItemWithUser[Issue]
13type CommentWithUser = ItemWithUser[Comment]
14
15@['/api/v1/:username/:repo_name/issues/count']
16fn (mut app App) handle_issues_count(username string, repo_name string) veb.Result {
17 has_access := app.has_user_repo_read_access_by_repo_name(ctx, ctx.user.id, username, repo_name)
18 if !has_access {
19 return ctx.json_error('Not found')
20 }
21 repo := app.find_repo_by_name_and_username(repo_name, username) or {
22 return ctx.json_error('Not found')
23 }
24 count := app.get_repo_issue_count(repo.id)
25 return ctx.json(api.ApiIssueCount{
26 success: true
27 result: count
28 })
29}
30
31@['/:username/:repo_name/issues/new']
32pub fn (mut app App) new_issue(username string, repo_name string) veb.Result {
33 if !ctx.logged_in {
34 return ctx.not_found()
35 }
36 repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() }
37 return $veb.html()
38}
39
40@['/:username/issues']
41pub fn (mut app App) handle_get_user_issues(mut ctx Context, username string) veb.Result {
42 return app.user_issues(mut ctx, username, 'created')
43}
44
45@['/:username/:repo_name/issues'; post]
46pub fn (mut app App) handle_add_repo_issue(mut ctx Context, username string, repo_name string) veb.Result {
47 // TODO: use captcha instead of user restrictions
48 if !ctx.logged_in || (ctx.logged_in && ctx.user.posts_count >= posts_per_day) {
49 return ctx.redirect_to_index()
50 }
51 repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() }
52 title := ctx.form['title']
53 text := ctx.form['text']
54 is_title_empty := validation.is_string_empty(title)
55 is_text_empty := validation.is_string_empty(text)
56 if is_title_empty || is_text_empty {
57 return ctx.redirect('/${username}/${repo_name}/issues/new')
58 }
59 app.increment_user_post(mut ctx.user) or { app.info(err.str()) }
60 app.add_issue(repo.id, ctx.user.id, title, text) or { app.info(err.str()) }
61 app.increment_repo_issues(repo.id) or { app.info(err.str()) }
62 app.dispatch_webhook(repo.id, 'issue', WebhookIssuePayload{
63 action: 'opened'
64 repo: '${username}/${repo_name}'
65 title: title
66 author: ctx.user.username
67 })
68 has_first_issue_activity := app.has_activity(ctx.user.id, 'first_issue')
69 if !has_first_issue_activity {
70 app.add_activity(ctx.user.id, 'first_issue') or { app.info(err.str()) }
71 }
72 return ctx.redirect('/${username}/${repo_name}/issues')
73}
74
75@['/:username/:repo_name/issues']
76pub fn (mut app App) handle_get_repo_issues(mut ctx Context, username string, repo_name string) veb.Result {
77 return app.issues(mut ctx, username, repo_name, '0')
78}
79
80@['/:username/:repo_name/issues/:page']
81pub fn (mut app App) issues(mut ctx Context, username string, repo_name string, page string) veb.Result {
82 repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() }
83 page_i := page.int()
84 mut issues_with_users := []IssueWithUser{}
85 mut issue := Issue{}
86 mut user := User{}
87 repo_issues := app.find_repo_issues_as_page(repo.id, page_i)
88 mut i := 0
89 for i = 0; i < repo_issues.len; i++ {
90 issue = repo_issues[i]
91 user = app.get_user_by_id(issue.author_id) or { continue }
92 issue.labels = app.get_issue_labels(issue.id)
93 issue.repo_author = repo.user_name
94 issue.repo_name = repo.name
95 issues_with_users << IssueWithUser{
96 item: issue
97 user: user
98 }
99 }
100 show_repo_link := false
101 mut first := false
102 mut last := false
103 if repo.nr_open_issues > commits_per_page {
104 offset := page_i * commits_per_page
105 delta := repo.nr_open_issues - offset
106 if delta > 0 {
107 if delta == repo.nr_open_issues && page_i == 0 {
108 first = true
109 } else {
110 last = true
111 }
112 }
113 } else {
114 last = true
115 first = true
116 }
117 page_count := calculate_pages(repo.nr_open_issues, commits_per_page)
118 prev_page, next_page := generate_prev_next_pages(page_i)
119 return $veb.html()
120}
121
122@['/:username/:repo_name/issue/:id']
123pub fn (mut app App) issue(mut ctx Context, username string, repo_name string, id string) veb.Result {
124 repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() }
125 issue := app.find_issue_by_id(id.int()) or { return ctx.not_found() }
126 issue_author := app.get_user_by_id(issue.author_id) or { return ctx.not_found() }
127 mut comments_with_users := []CommentWithUser{}
128 mut comment := Comment{}
129 mut comment_author := User{}
130 issue_comments := app.get_all_issue_comments(issue.id)
131 mut i := 0
132 for i = 0; i < issue_comments.len; i++ {
133 comment = issue_comments[i]
134 comment_author = app.get_user_by_id(comment.author_id) or { continue }
135 comments_with_users << CommentWithUser{
136 item: comment
137 user: comment_author
138 }
139 }
140 return $veb.html()
141}
142
143@['/:username/issues/:tab']
144pub fn (mut app App) user_issues(mut ctx Context, username string, tab string) veb.Result {
145 if !ctx.logged_in {
146 return ctx.not_found()
147 }
148 if ctx.user.username != username {
149 return ctx.not_found()
150 }
151 exists, user := app.check_username(username)
152 if !exists {
153 return ctx.not_found()
154 }
155 current_tab := if tab in ['assigned', 'created', 'mentioned', 'activity'] {
156 tab
157 } else {
158 'created'
159 }
160 mut issues := match current_tab {
161 'assigned' { []Issue{} }
162 'mentioned' { app.find_user_mentioned_issues(user.username) }
163 'activity' { app.find_user_recent_issues(user.id) }
164 else { app.find_user_issues(user.id) }
165 }
166
167 mut issue_repo := Repo{}
168 for mut issue in issues {
169 issue_repo = app.find_repo_by_id(issue.repo_id) or { continue }
170 issue.repo_author = issue_repo.user_name
171 issue.repo_name = issue_repo.name
172 issue.labels = app.get_issue_labels(issue.id)
173 }
174 mut issues_with_users := []IssueWithUser{}
175 for issue in issues {
176 issue_author := app.get_user_by_id(issue.author_id) or { continue }
177 issues_with_users << IssueWithUser{
178 item: issue
179 user: issue_author
180 }
181 }
182 tab_assigned_class := if current_tab == 'assigned' {
183 'user-issues-sidebar__item user-issues-sidebar__item--active'
184 } else {
185 'user-issues-sidebar__item'
186 }
187 tab_created_class := if current_tab == 'created' {
188 'user-issues-sidebar__item user-issues-sidebar__item--active'
189 } else {
190 'user-issues-sidebar__item'
191 }
192 tab_mentioned_class := if current_tab == 'mentioned' {
193 'user-issues-sidebar__item user-issues-sidebar__item--active'
194 } else {
195 'user-issues-sidebar__item'
196 }
197 tab_activity_class := if current_tab == 'activity' {
198 'user-issues-sidebar__item user-issues-sidebar__item--active'
199 } else {
200 'user-issues-sidebar__item'
201 }
202 show_repo_link := true
203 return $veb.html()
204}
205