diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a01d72b..197487fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,7 @@ on: [push, pull_request] jobs: ubuntu-gcc: runs-on: ubuntu-latest + timeout-minutes: 60 steps: - name: Checkout V uses: actions/checkout@v4 @@ -26,7 +27,8 @@ jobs: cd gitly v -cc gcc . - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -cc gcc -autofree . @@ -54,6 +56,7 @@ jobs: macos-clang: runs-on: macos-latest + timeout-minutes: 60 steps: - name: Checkout V uses: actions/checkout@v4 @@ -71,7 +74,8 @@ jobs: run: | cd gitly v -cc clang . - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -cc clang -autofree . @@ -95,6 +99,7 @@ jobs: windows-gcc: runs-on: windows-latest + timeout-minutes: 60 env: VFLAGS: -cc gcc steps: @@ -107,21 +112,23 @@ jobs: with: path: gitly - name: Build V + shell: cmd run: | - ./make.bat -gcc - - # Must come after "Build V": this used to run first, when neither `v` - # nor `v.exe` existed, so the referenced script could not work at all. + make.bat -gcc + # Must run after "Build V": the script shells out to `v.exe`, which + # does not exist until V is built. - name: Install SQLite - run: .\gitly\.github\workflows\windows-install-sqlite.bat - + shell: cmd + run: | + gitly\.github\workflows\windows-install-sqlite.bat - name: Compile gitly run: | dir - .\v.exe -cc gcc gitly + .\v.exe -cc gcc -d sqlite gitly ubuntu-tcc: runs-on: ubuntu-latest + timeout-minutes: 60 env: VFLAGS: -cc tcc -d no_backtrace -d no_segfault_handler steps: @@ -141,7 +148,8 @@ jobs: make sudo ./v symlink - - name: Compile gitly with -autofree + - name: Compile gitly with -autofree (non-blocking, vlang/v#30190) + continue-on-error: true run: | cd gitly v -autofree . diff --git a/gitly.v b/gitly.v index 66ae334f..b3d5562e 100644 --- a/gitly.v +++ b/gitly.v @@ -93,8 +93,8 @@ fn new_app() !&App { mut app := &App{ // db: sqlite.connect('gitly.sqlite') or { panic(err) } - db: connect_db(conf)! - config: conf + db: connect_db(conf)! + config: conf started_at: time.now().unix() } @@ -484,6 +484,9 @@ fn (mut app App) create_tables() ! { sql app.db { create table Comment }! + sql app.db { + create table CommentReaction + }! sql app.db { create table Branch }! @@ -914,7 +917,7 @@ fn (mut app App) add_missing_column(table_name string, column_name string, colum fn (mut ctx Context) json_success[T](result T) veb.Result { response := api.ApiSuccessResponse[T]{ success: true - result: result + result: result } return ctx.json(response) diff --git a/repo/comment.v b/repo/comment.v index f6e30995..2aa1d226 100644 --- a/repo/comment.v +++ b/repo/comment.v @@ -15,6 +15,30 @@ mut: text string } +struct CommentReaction { +mut: + id int @[primary; sql: serial] + comment_id int + user_id int + emoji string +} + +fn (mut app App) toggle_comment_reaction(cid int, uid int, em string) ! { + existing := sql app.db { + select from CommentReaction where comment_id == cid && user_id == uid && emoji == em + } or { []CommentReaction{} } + if existing.len > 0 { + sql app.db { + delete from CommentReaction where comment_id == cid && user_id == uid && emoji == em + }! + } else { + r := CommentReaction{ comment_id: cid, user_id: uid, emoji: em } + sql app.db { + insert r into CommentReaction + }! + } +} + @['/:username/:repo_name/comments'; post] pub fn (mut app App) handle_add_comment(mut ctx Context, username string, repo_name string) veb.Result { repo := app.find_repo_by_name_and_username(repo_name, username) or { return ctx.not_found() } @@ -62,9 +86,9 @@ fn (mut app App) add_issue_comment(author_id int, issue_id int, text string) ! { }! } -fn (mut app App) get_all_issue_comments(issue_id int) []Comment { +fn (mut app App) get_all_issue_comments(iid int) []Comment { comments := sql app.db { - select from Comment where issue_id == issue_id order by id + select from Comment where issue_id == iid order by id } or { []Comment{} } return comments @@ -73,3 +97,17 @@ fn (mut app App) get_all_issue_comments(issue_id int) []Comment { fn (c Comment) relative() string { return time.unix(c.created_at).relative() } + +@['/:username/:repo_name/comments/:comment_id/react'; post] +pub fn (mut app App) handle_toggle_comment_reaction(mut ctx Context, username string, repo_name string, comment_id string) veb.Result { + if !ctx.logged_in { + return ctx.not_found() + } + cid := comment_id.int() + emoji := ctx.form['emoji'] or { '' } + if emoji == '' { + return ctx.redirect('/${username}/${repo_name}') + } + app.toggle_comment_reaction(cid, ctx.user.id, emoji) or { app.info(err.str()) } + return ctx.redirect('/${username}/${repo_name}') +} diff --git a/repo/repo.v b/repo/repo.v index 68282424..6b9f2b06 100644 --- a/repo/repo.v +++ b/repo/repo.v @@ -29,12 +29,12 @@ mut: primary_branch string webhook_secret string tags_count int - nr_open_issues int @[orm: 'open_issues_count'] - nr_open_prs int @[orm: 'open_prs_count'] - nr_releases int @[orm: 'releases_count'] - nr_branches int @[orm: 'branches_count'] + nr_open_issues int @[sql: 'open_issues_count'] + nr_open_prs int @[sql: 'open_prs_count'] + nr_releases int @[sql: 'releases_count'] + nr_branches int @[sql: 'branches_count'] nr_tags int - nr_stars int @[orm: 'stars_count'] + nr_stars int @[sql: 'stars_count'] lang_stats []LangStat @[skip] created_at int nr_contributors int