From cccd3c66e6296329ae2445ad823877adc28411a0 Mon Sep 17 00:00:00 2001 From: tiger2005 <41613797+tiger2005@users.noreply.github.com> Date: Thu, 2 Dec 2021 16:24:30 +0800 Subject: [PATCH] Update "Problems" function of "Profile" page --- contest.html | 2 +- css/client.css | 92 ++++++++- css/dark.css | 10 +- css/default.css | 12 +- index.html | 33 ++- js/contest.js | 2 +- js/locale.js | 10 +- js/profile.js | 530 ++++++++++++++++++++++++++++++++++++++++++------ problem.html | 2 +- 9 files changed, 617 insertions(+), 76 deletions(-) diff --git a/contest.html b/contest.html index 654df0e..a333a28 100644 --- a/contest.html +++ b/contest.html @@ -29,7 +29,7 @@ - +
User Avatar diff --git a/css/client.css b/css/client.css index 22807f2..529f662 100644 --- a/css/client.css +++ b/css/client.css @@ -16,8 +16,8 @@ body{ margin: 0px; } :root{ - --font-family: 'Consolas','Fira Code','Source Code Pro','Lucida Console','Cascadia Code','Ubuntu Mono','Monospace', sans-serif; - --editor-font-family: 'Consolas','Fira Code','Source Code Pro','Lucida Console','Cascadia Code','Ubuntu Mono','Monospace', sans-serif; + --font-family: 'Consolas','Fira Code','Source Code Pro','Lucida Console','Cascadia Code','Ubuntu Mono',monospace, sans-serif; + --editor-font-family: 'Consolas','Fira Code','Source Code Pro','Lucida Console','Cascadia Code','Ubuntu Mono',monospace, sans-serif; } .HtmlContainer{ width: 1000px; @@ -1317,6 +1317,82 @@ pre{ /* PROFILE */ +.profileTagsBar{ + width: calc(100% - 50px); + height: 10px; + border-radius: 5px; + margin: 20px; + overflow: hidden; + display: flex; + flex-direction: row; + position: relative; +} +.profileProblemMain{ + flex: 1; + padding: 5px 10px; + border-radius: 5px; + width: calc(100% - 50px); + height: 20px; + overflow-y: auto; +} +.profileProblemBlock{ + width: calc(100% - 10px); + border: 3px 5px; + display: flex; + flex-direction: row; + font-size: 16px; + margin: 5px 0px; +} +.profileProblemTags{ + width: calc(100% - 10px); + text-align: right; + font-size: 16px; + margin: 5px 0px; +} +.profileProblemTags > .profileTagBox{ + margin: 0px 3px !important; + font-size: 12px !important; +} +.profileProblemSummary{ + justify-content: center; + padding: 5px 10px; + border-radius: 5px; + width: calc(100% - 50px); + height: 20px; + margin: 20px 10px; + margin-top: 10px; + display: flex; + flex-direction: row; +} +.problemTagsBarContent{ + height: 10px; + transition: 0.3s; +} +.problemTagsBarContent:hover{ + opacity: 0.7; +} +.profileTagsDisplayer{ + padding: 5px 10px; + border-radius: 5px; + width: calc(100% - 50px); + height: 100px; + overflow-y: auto; +} +.profileTagBox{ + display: inline-block; + margin: 3px; + padding: 3px 5px; + border-radius: 5px; + cursor: pointer; +} +.profileRatingGraph{ + border-radius: 5px; + margin: 15px; + width: calc(100% - 50px); + padding: 10px; + height: 100px; + position: relative; +} .infoOptions .disabled, .userInfoOptions .disabled{ color: #777; } @@ -1367,7 +1443,17 @@ pre{ place-items: center; outline: 0; } - +.profileSelectIf{ + transition: 0.3s; + height: 20px; + width: 20px; + border-radius: 10px; + margin: 0px 3px; + cursor: pointer; + display: grid; + place-items: center; + font-size: 14px; +} .setInlineBlock{ diff --git a/css/dark.css b/css/dark.css index 35a0542..73b7fe9 100644 --- a/css/dark.css +++ b/css/dark.css @@ -156,7 +156,15 @@ body{ .modulesBlock{ background: rgb(51, 56, 61); } - +.profileTagsDisplayer, .profileRatingGraph, .profileProblemSummary, .profileProblemMain{ + background: rgb(51, 56, 61); +} +.profileSelectIf:hover{ + background: rgb(71, 76, 81); +} +.profileSelectIf.selected{ + background: #777; +} diff --git a/css/default.css b/css/default.css index 424e50d..16c8d31 100644 --- a/css/default.css +++ b/css/default.css @@ -173,9 +173,15 @@ body{ .modulesBlock{ background: #ccc; } - - - +.profileTagsDisplayer, .profileRatingGraph, .profileProblemSummary, .profileProblemMain{ + background: #ccc; +} +.profileSelectIf:hover{ + background: #bbb; +} +.profileSelectIf.selected{ + background: #aaa; +} diff --git a/index.html b/index.html index a3f835f..004a988 100644 --- a/index.html +++ b/index.html @@ -41,7 +41,12 @@ } } - + +
@@ -583,7 +588,31 @@
-
+
+
+
+
+
+
+ +
+
+
+ + + + + + + + + + + + + +
+
diff --git a/js/contest.js b/js/contest.js index 34ae758..9a7e20f 100644 --- a/js/contest.js +++ b/js/contest.js @@ -13,7 +13,7 @@ var contestListFormatString = `
Open profile", userInfoOptionsObserve: " Observe status", - + Difficulty: "Diff.", }, input: { singleContestantUsername: "Username", @@ -150,6 +150,8 @@ var lang_en = { multiContestInfoInput1: "Blank", multiContestInfoInput2: "Room ID", infoUsernameInput: "Username", + minDiff: "Min", + maxDiff: "Max", }, error: { errorUsernameError: "Username Error", @@ -482,6 +484,8 @@ var lang_zh = { Rating: "Rating", userInfoOptionsProfile: " 个人信息", userInfoOptionsObserve: " 追踪状态", + Difficulty: "难度", + }, input: { @@ -500,6 +504,8 @@ var lang_zh = { usersPerPage: "每页用户数", multiStatus: "状态", infoUsernameInput: "用户名", + minDiff: "最小值", + maxDiff: "最大值", }, error: { errorUsernameError: "用户名错误", @@ -707,7 +713,7 @@ var lang_zh = { modules: { modulesOpen: " 打开", modulesProblemPage: "题目界面", - modulesProblemPageDesc: "在此界面添加一场比赛或者题目,利用 CCHv2 的快速加载和渲染更快查看题目。在此界面添加一场比赛或者题目,利用 CCHv2 的快速加载和渲染更快查看题目", + modulesProblemPageDesc: "在此界面添加一场比赛或者题目,利用 CCHv2 的快速加载和渲染更快查看题目。", modulesSubmissionPage: "提交记录界面", modulesSubmissionPageDesc: "你可以在这里查看所有的提交记录,并且通过适当的筛选找到自己想要的记录列表。", modulesBlogViewer: "博客查看器", diff --git a/js/profile.js b/js/profile.js index 3fb0fbc..2a1d244 100644 --- a/js/profile.js +++ b/js/profile.js @@ -1,3 +1,65 @@ +var ratingRanges = [ +{ + color: '#CCCCCC', + from: -9999, + to: 1200 +}, +{ + color: '#77FF77', + from: 1200, + to: 1400 +}, +{ + color: '#77DDBB', + from: 1400, + to: 1600 +}, +{ + color: '#AAAAFF', + from: 1600, + to: 1900 +}, +{ + color: '#FF88FF', + from: 1900, + to: 2100 +}, +{ + color: '#FFCC88', + from: 2100, + to: 2300 +}, +{ + color: '#FFBB55', + from: 2300, + to: 2400 +}, +{ + color: '#FF7777', + from: 2400, + to: 2600 +}, +{ + color: '#FF3333', + from: 2600, + to: 3000 +}, +{ + color: '#AA0000', + from: 3000, + to: 9999 +}, +]; +var profileInfoCurrentAsked = ""; +var profileInfoDatas = [{}, [], [], {}]; +var profileChosenTags = []; +var profileInfoLoaded = [false, false, false]; +var profileInfoLoaders = [null, null, null]; +var profileTagsToColor = {}, profileIdToTag = {}, profileTagToId = {}; +var profileProblemToSubmissions = {}; +var profileFilteredInfo, profilePageID; +// -- move to settings +const profilePageCount = 100; function getPP(data, frcd){ var cnt = []; for(var i=0; i<40; i++) @@ -38,13 +100,27 @@ function getACCounts(data){ if(q.verdict == "OK" && calc[p] == undefined) ++ ans, calc[p] = true; } + delete(calc); return ans; } - -var profileInfoCurrentAsked = ""; -var profileInfoDatas = [{}, [], [], {}]; -var profileInfoLoaded = [false, false, false]; -var profileInfoLoaders = [null, null, null]; +function getProblemsIf(data){ + var calc = {}; + var ret = []; + delete(profileProblemToSubmissions); + profileProblemToSubmissions = {}; + for(var i=0; i= 100000; + } +] + +function profileProblemFilter(d, mn, mx, ft){ + var ret = d; + if(mn != 0){ + var q = ret; + ret = []; + for(var i=0; i= mn) + ret.push(q[i]); + } + if(mx != 0){ + var q = ret; + ret = []; + for(var i=0; i${toDetailedInfo(curr.verdict, curr.testset)}` + else if(curr.verdict == undefined) + vid = `${toDetailedInfo(curr.verdict, curr.testset)}` + else if(curr.verdict == "TESTING") + vid = `${toDetailedInfo(curr.verdict, curr.testset)} on test ${curr.passedTestCount + 1}` + else if(curr.verdict == "PARTIAL" || curr.verdict == "COMPILATION_ERROR" || curr.verdict == "SKIPPED" || curr.verdict == "REJECTED") + vid = `${toDetailedInfo(curr.verdict, curr.testset)}` + else if(curr.verdict == "CHALLENGED") + vid = `${toDetailedInfo(curr.verdict, curr.testset)}` + else + vid = `${toDetailedInfo(curr.verdict, curr.testset)} on test ${curr.passedTestCount + 1}` + vid = $(vid); + vid.attr("onclick", `openSubmission(${curr.contestId}, ${curr.id})`); + vid.css("cursor", "pointer"); + vid = vid.prop("outerHTML"); + $(".eventList").append(`

${tim} ${vid}${curr.points != undefined || curr.pointsInfo != undefined ? ` | ${curr.pointsInfo != undefined ? curr.pointsInfo : curr.points}` : ""} [${toDetailedTestset(curr.testset)}]

`) + } +} +function getRandomColor(){ + var r = Math.random() * 128 + 64, g = Math.random() * 128 + 64, b = Math.random() * 128 + 64 + return [`rgb(${r}, ${g}, ${b})`, `rgba(${r}, ${g}, ${b}, 0.5)`]; +} +function renderProblemMain(){ + $(".profileProblemMain").html(""); + var len = Math.floor((profileFilteredInfo.length + profilePageCount - 1) / profilePageCount); + len = Math.max(len, 1); + profilePageID = Math.max(1, Math.min(len, profilePageID)); + var l = (profilePageID - 1) * profilePageCount; + var r = l + profilePageCount; + r = Math.min(r, profileFilteredInfo.length); + $(".profileProblemPages").html(`${profilePageID}/${len}`); + for(var i=l; i${profileFilteredInfo[i].tags[j]}`; + if(tgs == "") + tgs = `-`; + $(".profileProblemMain").append(`
${profileFilteredInfo[i].contestId + profileFilteredInfo[i].index}
${profileFilteredInfo[i].name} *${profileFilteredInfo[i].rating == undefined ? "?" : profileFilteredInfo[i].rating}
`) + $(".profileProblemMain").append(`
${tgs}
`); + } +} +$(".profilePageLeft").click(function(){ + -- profilePageID; + renderProblemMain(); +}) +$(".profilePageRight").click(function(){ + ++ profilePageID; + renderProblemMain(); +}) +function renderProfileProblemsPage(d, fir){ + var D = getProblemStatistics(d); + $(".profileTagsDisplayer").html(""); + $(".profileTagsBar").html(""); + if(fir){ + $(".profileTagsInput").html(""); + delete(profileIdToTag); profileIdToTag = {}; + delete(profileTagToId); profileTagToId = {}; + } + var passedQuestions = {}; + for(var i=0; iall: ${d.length}`); + for(var i=0; i`); + $(".profileTagsDisplayer").append(` ${tg}: ${ps}`) + } + if(D[0].length){ + for(var i=0; i`); + $(".profileTagsDisplayer").append(` ${D[0][i][0]}: ${D[0][i][1]}`) + } + } + var mx = 0; + for(var i=0; i= ratingRanges[i].from && x < ratingRanges[i].to) + return ratingRanges[i].color; + } + var wd = $(".profileRatingGraph").width(); + for(var i=800; i<=3500; i+=100){ + var currRating = i; + var currPassed = 0; + var prob = 0; + var col = getColorByRating(currRating); + if((i-800) % 3 == 0) + $(".profileRatingGraph").append(`${currRating}`) + $(".profileRatingGraph").append(`
`) + $(".profileRatingGraph").append(`${0}`) + } + $(".profileRatingGraphBarContent").click(function(){ + var num = $(this).attr("number"); + if($(".profileDiffInput[info=minDiff]").val() == num + && $(".profileDiffInput[info=maxDiff]").val() == num) + $(".profileDiffInput[info=minDiff]").val(""), + $(".profileDiffInput[info=maxDiff]").val(""); + else + $(".profileDiffInput[info=minDiff]").val(num), + $(".profileDiffInput[info=maxDiff]").val(num); + reloadProfileProblemPage(false); + }) + $(".profileRatingGraphDescContent").click(function(){ + var num = $(this).attr("number"); + if($(".profileDiffInput[info=minDiff]").val() == num + && $(".profileDiffInput[info=maxDiff]").val() == num) + $(".profileDiffInput[info=minDiff]").val(""), + $(".profileDiffInput[info=maxDiff]").val(""); + else + $(".profileDiffInput[info=minDiff]").val(num), + $(".profileDiffInput[info=maxDiff]").val(num); + reloadProfileProblemPage(false); + }) +} +function reloadProfileProblemPage(fir){ + var d = profileInfoDatas[2]; + var mn = $(".profileDiffInput[info=minDiff]").val(); + var mx = $(".profileDiffInput[info=maxDiff]").val(); + var ft = $(".profileTagsInput").val(); + var st = 0; + if($(".profileSelectSortID").hasClass("selected")) + st = 1; + else if($(".profileSelectSortRating").hasClass("selected")) + st = 2; + else + st = 3; + var dir = 0; + if($(".profileSelectSortDirection i").hasClass("fa-caret-down")) + dir = 1; + var D = getProblemsIf(d); + D = profileProblemFilter(D, Number(mn), Number(mx), ft); + D = profileProblemSort(D, st, dir); + renderProfileProblemsPage(D, fir); +} +initProfileRatingGraph(); + +$(".profileGoBack").click(function(){ + $(".infoContent > .contentRowInfo").css("left", "-920px"); +}) +$(".profileSortId").click(function(){ + $(".profileSortId.selected").removeClass("selected"); + $(this).addClass("selected"); + reloadProfileProblemPage(false); +}) +$(".profileSelectSortDirection").click(function(){ + if($(this).find("i").hasClass("fa-caret-down")) + $(this).find("i").attr("class", "fas fa-caret-up red"); + else + $(this).find("i").attr("class", "fas fa-caret-down green"); + reloadProfileProblemPage(false); +}) +$(".profileDiffInput").bind('input propertychange', function(){ + reloadProfileProblemPage(false); +}) +$(".profileTagsInput").bind('input propertychange', function(){ + reloadProfileProblemPage(false); +}) + function profileDrawGraph(data){ if(profileRatingCharts != null) profileRatingCharts.destroy(); @@ -107,63 +546,12 @@ function profileDrawGraph(data){ }, gridLineColor: "transparent", // tickPositions: [1200, 1400, 1600, 1900, 2100, 2300, 2400, 2600, 3000], - plotLines: [ - { - color: '#CCCCCC', - from: -9999, - to: 1200 - }, - { - color: '#77FF77', - from: 1200, - to: 1400 - }, - { - color: '#77DDBB', - from: 1400, - to: 1600 - }, - { - color: '#AAAAFF', - from: 1600, - to: 1900 - }, - { - color: '#FF88FF', - from: 1900, - to: 2100 - }, - { - color: '#FFCC88', - from: 2100, - to: 2300 - }, - { - color: '#FFBB55', - from: 2300, - to: 2400 - }, - { - color: '#FF7777', - from: 2400, - to: 2600 - }, - { - color: '#FF3333', - from: 2600, - to: 3000 - }, - { - color: '#AA0000', - from: 3000, - to: 9999 - }, - ] + plotLines: ratingRanges }; var tooltip = { borderRadius: 5, formatter: function () { - if(profileInfoDatas[3][this.x] == undefined) + if(profileInfoDatas[3] == undefined || profileInfoDatas[3][this.x] == undefined) return ""; var val = profileInfoDatas[1][profileInfoDatas[3][this.x]]; return `${languageOption.general.Rank}: ` + val.rank + ' | ' @@ -234,10 +622,14 @@ function infoLoadUsername(un){ $("[for=infoContent]").click(); for(var i=0; i<=2; i++) if(profileInfoLoaders[i] != null) - profileInfoLoaders.abort(); + profileInfoLoaders[i].abort(); var hCode = (new Date()).getTime(); profileInfoCurrentAsked = un + '#' + hCode; - profileInfoDatas = [{}, [], []]; + delete(profileInfoDatas[0]); + delete(profileInfoDatas[1]); + delete(profileInfoDatas[2]); + delete(profileInfoDatas[3]); + profileInfoDatas = [{}, [], [], {}]; profileInfoLoaded = [false, false, false] $(".infoShowProblems").addClass("disabled"); $(".infoShowSubmissions").addClass("disabled"); @@ -287,7 +679,7 @@ function infoLoadUsername(un){ $(".infoUserAvatar").attr("src", d.titlePhoto); $(".infoSmallUserRanks").html(`
${ratingToGrade(d.rating)}
`); $(".infoUsername").html(`
${d.handle}
`); - $(".infoUserRanksValue").html(`
${ratingToSmalln(d.rating)} ${d.rating}
(max.
${ratingToSmalln(d.maxRating)} ${d.maxRating}
)`); + $(".infoUserRanksValue").html(`
${ratingToSmalln(d.rating)} ${d.rating == undefined ? "0" : d.rating}
(max.
${ratingToSmalln(d.maxRating)} ${d.maxRating == undefined ? "0" : d.maxRating}
)`); $(".infoUserContributionValue").html(`${d.contribution == 0 ? 0 : (d.contribution > 0 ? `+${d.contribution}` : `${d.contribution}`)}`); $(".infoUserFriends > span").attr("argv", `[${d.friendOfCount}]`).html(languageOption.general.infoFriends.format([d.friendOfCount])); $(".infoUserTimes > div:first-child").html((new Date(d.registrationTimeSeconds * 1000)).pattern("yyyy-MM-dd hh:mm")); @@ -307,7 +699,7 @@ function infoLoadUsername(un){ infoLoadData(2, generateAuthorizeURL(settings.codeforcesApiUrl + '/user.status', {handle: un}), function(d){ profileInfoDatas[2] = d; $(".infoShowProblems").removeClass("disabled"); - $(".infoShowSubmissions").removeClass("disabled"); + // $(".infoShowSubmissions").removeClass("disabled"); $(".infoProblemSubmitted span").html(d.length); $(".infoProblemAccept span").html(getACCounts(d)); function dec(x){ @@ -315,8 +707,22 @@ function infoLoadUsername(un){ } $(".infoProblemContestPP span").html(dec(getPP(d, true))); $(".infoProblemPracticePP span").html(dec(getPP(d, false))); + delete(profileChosenTags); + profileChosenTags = []; + $(".profileTagsInput").val(":ac :contest"); + reloadProfileProblemPage(true); }); } +$(".infoShowProblems").click(function(){ + if($(this).hasClass("disabled")) + return; + $(".infoContent > .contentRowInfo").css("left", "0px"); +}) +$(".infoShowSubmissions").click(function(){ + if($(this).hasClass("disabled")) + return; + $(".infoContent > .contentRowInfo").css("left", "-1840px"); +}) function infoSetupUsername(){ if($(".infoChangeUsernameInputArea > button").hasClass("dangerColor")) return; diff --git a/problem.html b/problem.html index 20dbf60..978ffa8 100644 --- a/problem.html +++ b/problem.html @@ -32,7 +32,7 @@ - +