2323 st .session_state .repo_page_tokens = []
2424if 'repo_current_page_idx' not in st .session_state :
2525 st .session_state .repo_current_page_idx = 0
26+ if 'repo_total_videos' not in st .session_state :
27+ st .session_state .repo_total_videos = 0
28+ if 'repo_total_pages' not in st .session_state :
29+ st .session_state .repo_total_pages = 0
30+ if 'repo_loading' not in st .session_state :
31+ st .session_state .repo_loading = False
32+ if 'repo_error' not in st .session_state :
33+ st .session_state .repo_error = None
34+ if 'repo_action' not in st .session_state :
35+ st .session_state .repo_action = None
2636
2737# Configs
2838SEARCH_API_URL = Config .SEARCH_API_URL
3545IS_INTERNAL_ENV = Config .IS_INTERNAL_ENV
3646
3747
48+ def set_repo_action (action : str ) -> None :
49+ """Schedule a repository navigation action for the next render."""
50+ st .session_state .repo_action = action
51+
52+
3853def search_videos (query : str ):
3954 """Send search query to backend."""
4055 try :
@@ -62,6 +77,8 @@ def fetch_videos_page(page_token: str | None = None, page_size: int = REPO_PAGE_
6277 return {
6378 "videos" : data .get ("videos" , []),
6479 "next_page_token" : data .get ("next_page_token" ),
80+ "total_videos" : data .get ("total_videos" , 0 ),
81+ "total_pages" : data .get ("total_pages" , 0 ),
6582 }
6683 return {"error" : f"Fetch failed with status { resp .status_code } " }
6784 except requests .RequestException as e :
@@ -78,6 +95,8 @@ def load_repository_page(page_token: str | None = None, append: bool = False) ->
7895
7996 videos = result .get ("videos" , [])
8097 next_token = result .get ("next_page_token" )
98+ total_videos = result .get ("total_videos" , 0 ) or 0
99+ total_pages = result .get ("total_pages" , 0 ) or 0
81100
82101 if append :
83102 st .session_state .repo_pages .append (videos )
@@ -90,6 +109,8 @@ def load_repository_page(page_token: str | None = None, append: bool = False) ->
90109
91110 st .session_state .repo_videos = st .session_state .repo_pages [st .session_state .repo_current_page_idx ]
92111 st .session_state .repo_next_token = next_token
112+ st .session_state .repo_total_videos = total_videos
113+ st .session_state .repo_total_pages = total_pages
93114 st .session_state .repo_initialized = True
94115 return True , None
95116
@@ -102,6 +123,11 @@ def reset_repository_state() -> None:
102123 st .session_state .repo_pages = []
103124 st .session_state .repo_page_tokens = []
104125 st .session_state .repo_current_page_idx = 0
126+ st .session_state .repo_total_videos = 0
127+ st .session_state .repo_total_pages = 0
128+ st .session_state .repo_loading = False
129+ st .session_state .repo_error = None
130+ st .session_state .repo_action = None
105131
106132
107133def upload_files_to_backend (files_data : list [tuple [bytes , str , str ]]):
@@ -423,42 +449,88 @@ def delete_confirmation_dialog(hashed_identifier: str, filename: str):
423449
424450 current_page_idx = st .session_state .repo_current_page_idx
425451 total_loaded_pages = len (st .session_state .repo_pages )
426- has_more_pages = st .session_state .repo_next_token is not None
452+ repo_action = st .session_state .repo_action
453+ st .session_state .repo_action = None
454+
455+ if repo_action == "prev" and not st .session_state .repo_loading :
456+ if current_page_idx > 0 :
457+ st .session_state .repo_current_page_idx -= 1
458+ st .session_state .repo_videos = st .session_state .repo_pages [st .session_state .repo_current_page_idx ]
459+ st .session_state .repo_error = None
460+ st .rerun ()
461+
462+ if repo_action == "next" and not st .session_state .repo_loading :
463+ if current_page_idx + 1 < total_loaded_pages :
464+ st .session_state .repo_current_page_idx += 1
465+ st .session_state .repo_videos = st .session_state .repo_pages [st .session_state .repo_current_page_idx ]
466+ st .session_state .repo_error = None
467+ st .rerun ()
468+ elif st .session_state .repo_next_token :
469+ st .session_state .repo_loading = True
470+ try :
471+ with st .spinner ("Loading next page..." ):
472+ success , error = load_repository_page (
473+ page_token = st .session_state .repo_next_token ,
474+ append = True
475+ )
476+ finally :
477+ st .session_state .repo_loading = False
478+ if not success and error :
479+ st .session_state .repo_error = error
480+ else :
481+ st .session_state .repo_error = None
482+ st .rerun ()
427483
428- prev_disabled = current_page_idx <= 0
429- next_disabled = (current_page_idx >= total_loaded_pages - 1 ) and not has_more_pages
484+ current_page_idx = st .session_state .repo_current_page_idx
485+ total_loaded_pages = len (st .session_state .repo_pages )
486+ total_pages = st .session_state .repo_total_pages or 0
487+ total_videos = st .session_state .repo_total_videos or 0
488+
489+ prev_disabled = st .session_state .repo_loading or current_page_idx <= 0
490+ if st .session_state .repo_loading :
491+ next_disabled = True
492+ elif total_pages > 0 :
493+ next_disabled = (current_page_idx + 1 ) >= total_pages
494+ else :
495+ next_disabled = True
430496
431497 nav_info_col , nav_prev_col , nav_next_col = st .columns ([6 , 0.3 , 0.3 ])
432498
433499 with nav_info_col :
434- page_label = f"Page { current_page_idx + 1 } of { max (total_loaded_pages , 1 )} "
435- if has_more_pages :
436- page_label += " (more available)"
437- st .markdown (f"<div style='text-align:left;font-weight:600;'>{ page_label } </div>" , unsafe_allow_html = True )
500+ if total_pages > 0 :
501+ current_display_page = current_page_idx + 1
502+ else :
503+ current_display_page = 0
504+ page_label = f"Page { current_display_page } of { total_pages } "
505+ video_suffix = "video" if total_videos == 1 else "videos"
506+ page_label += f" • { total_videos } { video_suffix } "
507+ st .markdown (
508+ f"<div style='text-align:left;font-weight:600;'>{ page_label } </div>" ,
509+ unsafe_allow_html = True
510+ )
438511
439512 with nav_prev_col :
440- if st .button ("◄" , disabled = prev_disabled , use_container_width = True , key = "repo_prev_btn" ):
441- if current_page_idx > 0 :
442- st .session_state .repo_current_page_idx -= 1
443- st .session_state .repo_videos = st .session_state .repo_pages [st .session_state .repo_current_page_idx ]
444- st .rerun ()
513+ st .button (
514+ "◄" ,
515+ disabled = prev_disabled ,
516+ use_container_width = True ,
517+ key = "repo_prev_btn" ,
518+ on_click = set_repo_action ,
519+ args = ("prev" ,),
520+ )
445521
446522 with nav_next_col :
447- if st .button ("►" , disabled = next_disabled , use_container_width = True , key = "repo_next_btn" ):
448- if current_page_idx + 1 < total_loaded_pages :
449- st .session_state .repo_current_page_idx += 1
450- st .session_state .repo_videos = st .session_state .repo_pages [st .session_state .repo_current_page_idx ]
451- st .rerun ()
452- elif st .session_state .repo_next_token :
453- with st .spinner ("Loading next page..." ):
454- success , error = load_repository_page (
455- page_token = st .session_state .repo_next_token ,
456- append = True
457- )
458- if not success and error :
459- st .error (f"Failed to load additional videos: { error } " )
460- else :
461- st .rerun ()
523+ st .button (
524+ "►" ,
525+ disabled = next_disabled ,
526+ use_container_width = True ,
527+ key = "repo_next_btn" ,
528+ on_click = set_repo_action ,
529+ args = ("next" ,),
530+ )
531+
532+ if st .session_state .repo_error :
533+ st .error (f"Failed to load additional videos: { st .session_state .repo_error } " )
462534
463535 if videos :
464536 # Create a grid of videos
0 commit comments