Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to this maintained LibreTV fork are documented here.

## 1.2.11 - 2026-05-12

### Fixed

- Search results now require title relevance so sources that ignore keywords cannot flood unrelated adult content into normal searches.
- The `成人视频` home tag now loads latest entries from selected adult sources instead of querying Douban as a normal tag.
- Normal Douban home categories now filter adult-looking cards and keep adult content isolated to the dedicated adult tag.

## 1.2.10 - 2026-05-12

### Changed
Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
202605120057
202605120120
74 changes: 73 additions & 1 deletion js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,17 @@ const YELLOW_CONTENT_KEYWORDS = [
'伦理片', '福利', '里番动漫', '门事件', '萝莉少女', '制服诱惑', '国产传媒',
'cosplay', '黑丝诱惑', '无码', '日本无码', '有码', '日本有码', 'swag',
'网红主播', '美女主播', '国产自拍', '色情片', '同性片', '福利视频', '福利片',
'成人', '情色', '女优', '人妻', '巨乳', '私拍', '大尺度', '麻豆', '抖阴'
'成人', '情色', '女优', '人妻', '巨乳', '私拍', '大尺度', '麻豆', '抖阴',
'热舞', '裸聊', '自慰', '做爱', '性交', '口交', '约炮', '无码流出',
'番号', '爆乳', '翘臀', '嫩模', '嫩妹', '美乳', '白丝', '丝袜', '写真'
];

const SEARCH_TITLE_FIELDS = [
'vod_name',
'vod_sub',
'vod_en',
'title',
'name'
];

function isYellowContentFilterEnabled() {
Expand All @@ -37,19 +47,68 @@ function getSearchableApiIds(apiIds = selectedAPIs) {
return ids.filter(apiId => !isAdultSourceId(apiId));
}

function getSelectedAdultApiIds(apiIds = selectedAPIs) {
return Array.from(apiIds || []).filter(apiId => isAdultSourceId(apiId));
}

function shouldShowAdultRecommendTag() {
return !isYellowContentFilterEnabled() && getSelectedAdultApiIds().length > 0;
}

function normalizeFilterText(value) {
return String(value || '').toLowerCase();
}

function normalizeSearchText(value) {
return String(value || '').toLowerCase().replace(/\s+/g, '');
}

function getSearchTitleTexts(item) {
return SEARCH_TITLE_FIELDS
.map(field => normalizeSearchText(item?.[field]))
.filter(Boolean);
}

function doesResultMatchQuery(item, query) {
const compactQuery = normalizeSearchText(query);
if (!compactQuery) return true;

const titleTexts = getSearchTitleTexts(item);
if (titleTexts.some(text => text.includes(compactQuery))) {
return true;
}

const queryTerms = String(query || '')
.toLowerCase()
.split(/\s+/)
.map(normalizeSearchText)
.filter(Boolean);

return queryTerms.length > 1 && queryTerms.every(term =>
titleTexts.some(text => text.includes(term))
);
}

function filterResultsByQuery(results, query) {
const list = Array.isArray(results) ? results : [];
return list.filter(item => doesResultMatchQuery(item, query));
}

function matchesYellowContent(item) {
if (isAdultSourceId(item?.source_code)) return true;

const haystack = [
item?.vod_name,
item?.vod_sub,
item?.vod_en,
item?.title,
item?.name,
item?.type_name,
item?.vod_class,
item?.vod_remarks,
item?.vod_content,
item?.desc,
item?.description,
item?.source_name
].map(normalizeFilterText).join(' ');

Expand Down Expand Up @@ -422,6 +481,10 @@ function updateSelectedAPIs() {

// 更新显示选中的API数量
updateSelectedApiCount();

if (typeof window.refreshDoubanAdultTagState === 'function') {
window.refreshDoubanAdultTagState();
}
Comment on lines +485 to +487

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update adult-tag visibility on custom API add/remove flows

The Douban adult-tag refresh is only wired into updateSelectedAPIs(), but adding/removing custom APIs mutates selectedAPIs through separate paths that do not call this function. As a result, adding the first adult custom source (or removing the last one) can leave the 成人视频 tab visibility stale until another toggle/change event or reload happens.

Useful? React with 👍 / 👎.

}

// 更新选中的API数量显示
Expand Down Expand Up @@ -617,6 +680,11 @@ function setupEventListeners() {
// 添加成人API列表
addAdultAPI();
}

checkAdultAPIsSelected();
if (typeof window.refreshDoubanAdultTagState === 'function') {
window.refreshDoubanAdultTagState();
}
});
}

Expand Down Expand Up @@ -1373,6 +1441,10 @@ function saveStringAsFile(content, fileName) {
}

window.getSearchableApiIds = getSearchableApiIds;
window.getSelectedAdultApiIds = getSelectedAdultApiIds;
window.shouldShowAdultRecommendTag = shouldShowAdultRecommendTag;
window.doesResultMatchQuery = doesResultMatchQuery;
window.filterResultsByQuery = filterResultsByQuery;
window.filterYellowContentResults = filterYellowContentResults;
window.matchesYellowContent = matchesYellowContent;
window.getResultTypeLabel = getResultTypeLabel;
Expand Down
2 changes: 1 addition & 1 deletion js/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const SITE_CONFIG = {
url: '',
description: '免费在线视频搜索与观看平台',
logo: 'image/logo.png',
version: '1.2.10'
version: '1.2.11'
};

const DEFAULT_SELECTED_APIS = ['ysgc', 'jszy', 'wujin', 'maoyan'];
Expand Down
Loading
Loading