diff options
-rw-r--r-- | pttbbs/include/proto.h | 1 | ||||
-rw-r--r-- | pttbbs/mbbsd/brc.c | 69 | ||||
-rw-r--r-- | pttbbs/mbbsd/read.c | 56 | ||||
-rw-r--r-- | pttbbs/sample/etc/board.help | 1 |
4 files changed, 127 insertions, 0 deletions
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h index 9e5b26df..b7882091 100644 --- a/pttbbs/include/proto.h +++ b/pttbbs/include/proto.h @@ -115,6 +115,7 @@ int brc_initial_board(const char *boardname); // v3 api: add 'modified' tag int brc_unread(int bid, const char *fname, time4_t modified); int brc_unread_time(int bid, time4_t ftime,time4_t modified); +int brc_search_read(int bid, time4_t ftime, int forward, time4_t *result); void brc_addlist(const char* fname, time4_t modified); void brc_update(void); void brc_toggle_all_read(int bid, int is_all_read); diff --git a/pttbbs/mbbsd/brc.c b/pttbbs/mbbsd/brc.c index bedb2e1a..8f7bf5ba 100644 --- a/pttbbs/mbbsd/brc.c +++ b/pttbbs/mbbsd/brc.c @@ -646,3 +646,72 @@ brc_unread(int bid, const char *fname, time4_t modified) return brc_unread_time(bid, ftime, modified); } + +/* + * 從 ftime 該篇文章開始, 往上或往下尋找第一篇已讀過的文章 + * forward == 1: 往更新的文章找 (往下找) + * + * 假設: blist[] 是按照 .create 由大而小往後排序好的. + * + * Return: 0 -- 沒有任何已讀的文章 + * 1 -- 找到已讀文章, 並將該文章放在 result 中傳回. + */ +int +brc_search_read(int bid, time4_t ftime, int forward, time4_t *result) +{ + int i; + int bnum; + const brc_rec *blist; + + brc_initialize(); + + if (brc_currbid && bid == brc_currbid) { + blist = brc_list; + bnum = brc_num; + } else { + blist = brc_find_record(bid, &bnum); + } + + // [0].create is the biggest. + // 首先要找到 ftime 所在的區間, 然後再視 forward 的值來取前後的已讀文章. + for( i = 0; i < bnum; i++ ) { /* using linear search */ + if( ftime > blist[i].create ) { + if( forward ) { + if( i ) { + goto return_older; + } else { + return 0; + } + } else { + // 回傳此篇已讀文章 + if( result ) *result = blist[i].create; + return 1; + } + } + // 游標所在的檔案本身就是已讀過 + else if( ftime == blist[i].create ) { + if( forward && i ) { + goto return_older; + } else if( !forward && (i + 1) < bnum ) { + goto return_newer; + } + return 0; + } + } + // 區間落在最後一個的後面 (更早之前的文章) + if ( forward && i ) { + goto return_older; + } + return 0; + +return_older: + // 回傳後一篇已讀文章 + if( result ) *result = blist[i - 1].create; + return 1; + +return_newer: + // 回傳前一篇已讀文章 + if( result ) *result = blist[i + 1].create; + return 1; +} + diff --git a/pttbbs/mbbsd/read.c b/pttbbs/mbbsd/read.c index 1999d82a..50e24561 100644 --- a/pttbbs/mbbsd/read.c +++ b/pttbbs/mbbsd/read.c @@ -330,6 +330,54 @@ thread(const keeploc_t * locmem, int stypen) return new_ln; } +/* + * 根據 stypen 選擇上/下一篇已讀過的文章 + * + * @param locmem 用來存在某看板游標位置的 structure。 + * @param stypen 游標移動的方法 + * CURSOR_NEXT, CURSOR_PREV: + * 與游標目前位置的文章同標題 的 下一篇/前一篇 文章。 + * + * @return 新的游標位置 + */ +static int +search_read(const int bid, const keeploc_t * locmem, int stypen) +{ + fileheader_t fh; + int pos = locmem->crs_ln; + int rk; + int fd = -1; + int forward = (stypen & RS_FORWARD) ? 1 : 0; + time4_t ftime, result; + + if( last_line <= 1 ) return pos; + + /* First load the timestamp of article where cursor pointing to */ + rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), pos, &fd); + if( fd < 0 || rk < 0) return pos; + ftime = atoi( &fh.filename[2] ); + + /* given the ftime to resolve the read article */ + if( brc_search_read(bid, ftime, forward, &result ) ) { + int i; + int step = forward ? 1 : -1; + + /* find out the position for the article result */ + for( i = pos; i >= 0 && i <= last_line; i += step ) { + rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), i, &fd); + if( fd < 0 || rk < 0) goto out; + if (atoi( &fh.filename[2] ) == result ) { + pos = i; + goto out; + } + } + } + +out: + if( fd != -1 ) close(fd); + return pos; +} + static int select_by_aid(const keeploc_t * locmem, int *pnew_ln, int *pnewdirect_new_ln, char *pdefault_ch) @@ -999,6 +1047,14 @@ i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem, } break; + case '{': + new_ln = search_read(bid, locmem, READ_PREV); + break; + + case '}': + new_ln = search_read(bid, locmem, READ_NEXT); + break; + case KEY_ENTER: case 'l': case KEY_RIGHT: diff --git a/pttbbs/sample/etc/board.help b/pttbbs/sample/etc/board.help index 4b9653a4..99181de1 100644 --- a/pttbbs/sample/etc/board.help +++ b/pttbbs/sample/etc/board.help @@ -5,6 +5,7 @@ (數字鍵) 跳到指定號碼的文章 (Home)/(End/$) 跳到首篇/末篇文章 (r)(→) 閱讀此篇文章 (=[]<>-+S) 主題式閱讀 (^P)/(y)/(X) [1m發表/回覆/推薦文章[m (F/U)/(^X) 轉寄至信箱/轉錄至其它看板 + ({)/(}) 跳到下篇已讀文章/上篇 [36m【 進階命令 】[m (/)(?)/(a)/(Z) 搜尋 關鍵字/作者/推文數 (^H)/(!) 只列主要標題/不列關鍵字 |