Refactor: Ohli24 UI refinement and mobile responsiveness fixes
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
title: "애니 다운로더"
|
||||
version: "0.5.35"
|
||||
version: "0.5.36"
|
||||
package_name: "anime_downloader"
|
||||
developer: "projectdx"
|
||||
description: "anime downloader"
|
||||
|
||||
@@ -9,10 +9,10 @@ from datetime import datetime
|
||||
import requests
|
||||
|
||||
# from flaskfarm.lib.plugin import get_model_setting
|
||||
from flaskfarm.lib.support.expand.ffmpeg import SupportFfmpeg
|
||||
from support.expand.ffmpeg import SupportFfmpeg
|
||||
|
||||
# from flaskfarm.lib.system.setup import SystemModelSetting
|
||||
from flaskfarm.lib.tool import ToolUtil
|
||||
from tool import ToolUtil
|
||||
|
||||
# from flaskfarm.lib.system.setup import P as SM
|
||||
# from flaskfarm.lib.system.mod_setting import ModuleSetting as SM
|
||||
|
||||
@@ -690,7 +690,7 @@ class LogicAniLife(AnimeModuleBase):
|
||||
"msg": "%s 개의 에피소드를 큐에 추가 하였습니다." % count,
|
||||
}
|
||||
socketio.emit(
|
||||
"notify", notify, namespace="/framework", broadcast=True
|
||||
"notify", notify, namespace="/framework"
|
||||
)
|
||||
thread = threading.Thread(target=func, args=())
|
||||
thread.daemon = True
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from flask import render_template, request, jsonify
|
||||
from flaskfarm.lib.plugin import PluginModuleBase
|
||||
from plugin import PluginModuleBase
|
||||
import framework
|
||||
import os, traceback, time, json
|
||||
from datetime import datetime
|
||||
@@ -177,7 +177,7 @@ class AnimeModuleBase(PluginModuleBase):
|
||||
namespace = f"/{self.P.package_name}/{self.name}/queue"
|
||||
|
||||
# 큐 페이지 소켓에 직접 emit
|
||||
socketio.emit(refresh_type, data, namespace=namespace, broadcast=True)
|
||||
socketio.emit(refresh_type, data, namespace=namespace)
|
||||
|
||||
except Exception as e:
|
||||
self.P.logger.error(f"socketio_callback error: {e}")
|
||||
|
||||
@@ -22,7 +22,7 @@ from bs4 import BeautifulSoup
|
||||
|
||||
# third-party
|
||||
from flask import jsonify, render_template, request
|
||||
from flaskfarm.lib.support.expand.ffmpeg import SupportFfmpeg
|
||||
from support.expand.ffmpeg import SupportFfmpeg
|
||||
|
||||
# sjva 공용
|
||||
from framework import db, path_data, scheduler
|
||||
@@ -479,7 +479,7 @@ class LogicLinkkf(AnimeModuleBase):
|
||||
"""
|
||||
logger.info(f">>> socketio_callback called: {refresh_type}, {data.get('percent', 'N/A')}%")
|
||||
try:
|
||||
from flaskfarm.lib.framework.init_main import socketio
|
||||
from framework import socketio
|
||||
|
||||
# FlaskFarm의 기존 패턴: /framework namespace로 emit
|
||||
# queue 페이지의 소켓이 이 메시지를 받아서 처리
|
||||
|
||||
@@ -530,7 +530,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"type": "success",
|
||||
"msg": "%s 개의 에피소드를 큐에 추가 하였습니다." % count,
|
||||
}
|
||||
socketio.emit("notify", notify, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", notify, namespace="/framework")
|
||||
|
||||
thread = threading.Thread(target=func, args=())
|
||||
thread.daemon = True
|
||||
@@ -2091,7 +2091,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
+ args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
refresh_type = "add"
|
||||
elif args["type"] == "last":
|
||||
entity = self.queue.get_entity_by_entity_id(args['data']['callback_id'])
|
||||
@@ -2099,7 +2099,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
if args["status"] == SupportFfmpeg.Status.WRONG_URL:
|
||||
if entity: entity.download_failed("WRONG_URL")
|
||||
data = {"type": "warning", "msg": "잘못된 URL입니다"}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "add"
|
||||
elif args["status"] == SupportFfmpeg.Status.WRONG_DIRECTORY:
|
||||
if entity: entity.download_failed("WRONG_DIRECTORY")
|
||||
@@ -2107,7 +2107,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"type": "warning",
|
||||
"msg": "잘못된 디렉토리입니다.<br>" + args["data"]["save_fullpath"],
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "add"
|
||||
elif args["status"] == SupportFfmpeg.Status.ERROR or args["status"] == SupportFfmpeg.Status.EXCEPTION:
|
||||
if entity: entity.download_failed("ERROR/EXCEPTION")
|
||||
@@ -2115,7 +2115,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"type": "warning",
|
||||
"msg": "다운로드 시작 실패.<br>" + args["data"]["save_fullpath"],
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "add"
|
||||
elif args["status"] == SupportFfmpeg.Status.USER_STOP:
|
||||
if entity: entity.download_failed("USER_STOP")
|
||||
@@ -2124,7 +2124,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "다운로드가 중지 되었습니다.<br>" + args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.COMPLETED:
|
||||
logger.debug("download completed........")
|
||||
@@ -2134,7 +2134,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.TIME_OVER:
|
||||
@@ -2144,7 +2144,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "시간초과로 중단 되었습니다.<br>" + args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.PF_STOP:
|
||||
if entity: entity.download_failed("PF_STOP")
|
||||
@@ -2153,7 +2153,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "PF초과로 중단 되었습니다.<br>" + args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.FORCE_STOP:
|
||||
if entity: entity.download_failed("FORCE_STOP")
|
||||
@@ -2162,7 +2162,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "강제 중단 되었습니다.<br>" + args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.HTTP_FORBIDDEN:
|
||||
if entity: entity.download_failed("HTTP_FORBIDDEN")
|
||||
@@ -2171,7 +2171,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "403에러로 중단 되었습니다.<br>" + args["data"]["save_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["status"] == SupportFfmpeg.Status.ALREADY_DOWNLOADING:
|
||||
# Already downloading usually means logic error or race condition, maybe not fail DB?
|
||||
@@ -2181,7 +2181,7 @@ class LogicOhli24(AnimeModuleBase):
|
||||
"msg": "임시파일폴더에 파일이 있습니다.<br>" + args["data"]["temp_fullpath"],
|
||||
"url": "/ffmpeg/download/list",
|
||||
}
|
||||
socketio.emit("notify", data, namespace="/framework", broadcast=True)
|
||||
socketio.emit("notify", data, namespace="/framework")
|
||||
refresh_type = "last"
|
||||
elif args["type"] == "normal":
|
||||
if args["status"] == SupportFfmpeg.Status.DOWNLOADING:
|
||||
@@ -2791,25 +2791,25 @@ class Ohli24QueueEntity(AnimeQueueEntity):
|
||||
# data = {'type': 'info',
|
||||
# 'msg': '다운로드중 Duration(%s)' % args['data']['duration_str'] + '<br>' + args['data'][
|
||||
# 'save_fullpath'], 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'add'
|
||||
# elif args['type'] == 'last':
|
||||
# if args['status'] == SupportFfmpeg.Status.WRONG_URL:
|
||||
# data = {'type': 'warning', 'msg': '잘못된 URL입니다'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'add'
|
||||
# elif args['status'] == SupportFfmpeg.Status.WRONG_DIRECTORY:
|
||||
# data = {'type': 'warning', 'msg': '잘못된 디렉토리입니다.<br>' + args['data']['save_fullpath']}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'add'
|
||||
# elif args['status'] == SupportFfmpeg.Status.ERROR or args['status'] == SupportFfmpeg.Status.EXCEPTION:
|
||||
# data = {'type': 'warning', 'msg': '다운로드 시작 실패.<br>' + args['data']['save_fullpath']}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'add'
|
||||
# elif args['status'] == SupportFfmpeg.Status.USER_STOP:
|
||||
# data = {'type': 'warning', 'msg': '다운로드가 중지 되었습니다.<br>' + args['data']['save_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.COMPLETED:
|
||||
# logger.debug('ffmpeg download completed......')
|
||||
@@ -2818,32 +2818,32 @@ class Ohli24QueueEntity(AnimeQueueEntity):
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
#
|
||||
#
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.TIME_OVER:
|
||||
# data = {'type': 'warning', 'msg': '시간초과로 중단 되었습니다.<br>' + args['data']['save_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.PF_STOP:
|
||||
# data = {'type': 'warning', 'msg': 'PF초과로 중단 되었습니다.<br>' + args['data']['save_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.FORCE_STOP:
|
||||
# data = {'type': 'warning', 'msg': '강제 중단 되었습니다.<br>' + args['data']['save_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.HTTP_FORBIDDEN:
|
||||
# data = {'type': 'warning', 'msg': '403에러로 중단 되었습니다.<br>' + args['data']['save_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['status'] == SupportFfmpeg.Status.ALREADY_DOWNLOADING:
|
||||
# data = {'type': 'warning', 'msg': '임시파일폴더에 파일이 있습니다.<br>' + args['data']['temp_fullpath'],
|
||||
# 'url': '/ffmpeg/download/list'}
|
||||
# socketio.emit("notify", data, namespace='/framework', broadcast=True)
|
||||
# socketio.emit("notify", data, namespace='/framework')
|
||||
# refresh_type = 'last'
|
||||
# elif args['type'] == 'normal':
|
||||
# if args['status'] == SupportFfmpeg.Status.DOWNLOADING:
|
||||
|
||||
@@ -73,8 +73,18 @@
|
||||
flex-wrap: wrap; /* allow wrap on small screens */
|
||||
justify-content: center;
|
||||
width: auto !important; /* Prevent full width */
|
||||
margin-bottom: 20px;
|
||||
margin-top: 50px !important; /* Mobile spacing */
|
||||
margin-bottom: 5px; /* Reduced for modularity */
|
||||
margin-top: 50px !important; /* Mobile spacing - fallback for first menu */
|
||||
}
|
||||
|
||||
/* Tighten spacing between 2nd and 3rd level menus */
|
||||
#menu_module_div ul.nav.nav-pills.bg-light {
|
||||
margin-bottom: 5px !important;
|
||||
}
|
||||
|
||||
#menu_page_div ul.nav.nav-pills.bg-light {
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
ul.nav.nav-pills .nav-item {
|
||||
|
||||
@@ -98,7 +98,7 @@ body {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
/* Nav Pills Customization */
|
||||
/* Nav Pills Customization (Shared styling, overrides in mobile_custom.css) */
|
||||
ul.nav.nav-pills.bg-light {
|
||||
background-color: rgba(30, 41, 59, 0.6) !important;
|
||||
backdrop-filter: blur(10px);
|
||||
@@ -110,7 +110,7 @@ ul.nav.nav-pills.bg-light {
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
width: auto !important;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 5px; /* Default for modular stacking */
|
||||
}
|
||||
|
||||
ul.nav.nav-pills .nav-link {
|
||||
@@ -155,6 +155,29 @@ ul.nav.nav-pills .nav-link.active {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Responsive Input Group for Search */
|
||||
.input-group-responsive {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.input-group-responsive .form-control {
|
||||
height: 100% !important;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.input-group-responsive .btn {
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.input-group-responsive {
|
||||
height: 42px;
|
||||
}
|
||||
.input-group-responsive .form-control {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-search { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); color: white !important; }
|
||||
.btn-reset { background: rgba(148, 163, 184, 0.1); color: #94a3b8 !important; }
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% extends "base.html" %} {% block content %}
|
||||
<link rel="stylesheet" href="{{ url_for('.static', filename='css/mobile_custom.css') }}"/>
|
||||
<link rel="stylesheet" href="{{ url_for('.static', filename='css/' ~ arg['sub'] ~ '.css') }}"/>
|
||||
<link rel="stylesheet" href="{{ url_for('.static', filename='css/video_modal.css') }}"/>
|
||||
|
||||
<div id="preloader">
|
||||
<div class="demo">
|
||||
@@ -59,6 +60,9 @@
|
||||
</form>
|
||||
</div>
|
||||
<!--전체-->
|
||||
<!-- Video Modal Component -->
|
||||
{% include 'anime_downloader/components/video_modal.html' %}
|
||||
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css">
|
||||
<script src="{{ url_for('.static', filename='js/sjva_ui14.js') }}"></script>
|
||||
|
||||
@@ -188,7 +192,7 @@
|
||||
|
||||
// Standard Actions
|
||||
if (data.first_exist_filepath) {
|
||||
str += `<button type="button" class="btn btn-success btn-sm mr-2" onclick="play_video('${data.first_exist_filepath.replace(/\\/g, '\\\\')}', '${data.first_exist_filename}')"><i class="fa fa-play"></i> 재생</button>`;
|
||||
str += `<button type="button" class="btn btn-success btn-sm mr-2 btn-watch" data-path="${data.first_exist_filepath.replace(/\\/g, '\\\\')}"><i class="fa fa-play"></i> 보기</button>`;
|
||||
}
|
||||
str += `<button id="check_download_btn" class="btn btn-primary btn-sm"><i class="fa fa-download"></i> 선택 다운로드</button>`;
|
||||
str += `<button id="all_check_on_btn" class="btn btn-outline-light btn-sm">전체 선택</button>`;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
<div class="row align-items-center">
|
||||
<div class="col-md-8 mx-auto">
|
||||
<div class="input-group input-group-lg">
|
||||
<div class="input-group input-group-responsive">
|
||||
<input
|
||||
id="input_search"
|
||||
type="search"
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
const wait3seconds = function () {
|
||||
// REFERENCE: https://www.w3schools.com/jsref/met_win_settimeout.asp
|
||||
const result = setTimeout(dismissLoadingScreen, 2000);
|
||||
const result = setTimeout(dismissLoadingScreen, 1000);
|
||||
};
|
||||
|
||||
window.addEventListener("load", wait3seconds);
|
||||
|
||||
Reference in New Issue
Block a user