diff --git a/src/components/render-html.jsx b/src/components/render-html.jsx index bcebb663..3b7e4b52 100644 --- a/src/components/render-html.jsx +++ b/src/components/render-html.jsx @@ -3,10 +3,12 @@ import 'katex/dist/katex.min.css' import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked'; import 'code-prettify' import dompurify from 'dompurify'; +import { getEmoji } from '../forge/Main/emoji'; import { renderToString } from 'katex' -const preRegex = /]*>/g +const preRegex = /]*>/g; +const strRegexSub = /:([a-zA-Z_]+):/g; function _unescape(str) { let div = document.createElement('div') div.innerHTML = str @@ -29,6 +31,13 @@ export default ({ rs = rs.replace("

[TOC]

", getTocContent()) cleanToc() } + let matchStr = str.match(strRegexSub); + if(matchStr && matchStr.length>0){ + for(var i=0;i < matchStr.length;i++){ + rs = rs.replace(matchStr[i],getEmoji(matchStr[i])); + } + } + rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => { const { type, expression } = math_expressions[capture]; return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' }) diff --git a/src/forge/Main/CoderDepotCatalogue.jsx b/src/forge/Main/CoderDepotCatalogue.jsx index 68434933..f13fded2 100644 --- a/src/forge/Main/CoderDepotCatalogue.jsx +++ b/src/forge/Main/CoderDepotCatalogue.jsx @@ -1,7 +1,7 @@ -import React from 'react'; +import React , { useEffect } from 'react'; import { Link } from 'react-router-dom'; import { truncateCommitId } from '../common/util'; - +import {getEmoji} from './emoji'; const typeIco = { "submodule":"icon-file-submodule font-17", "file":'icon-wenjian6 font-15 color-blue-file', @@ -11,9 +11,19 @@ const typeIco = { function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId , platform }){ // 只显示第一个换行符前的内容 function getMessage(value){ - let str = value.indexOf('\n') > 0 && value.split('\n'); - return str[0]; + var matchStr = value.match(/:([a-zA-Z_]+):/g); + if(matchStr && matchStr.length>0){ + for(var i=0;i < matchStr.length;i++){ + value = value.replace(matchStr[i],getEmoji(matchStr[i])); + } + } + return value; } + + useEffect(()=>{ + + },[]) + return(
  • @@ -28,7 +38,7 @@ function CoderDepotCatalogue({item , goToSubRoot , owner , projectsId , platform - {getMessage(item.commit && item.commit.message)} + {getEmoji(getMessage(item.commit && item.commit.message))} {item.commit && item.commit.time_from_now} diff --git a/src/forge/Main/emoji/index.jsx b/src/forge/Main/emoji/index.jsx new file mode 100644 index 00000000..306db1e4 --- /dev/null +++ b/src/forge/Main/emoji/index.jsx @@ -0,0 +1,462 @@ +const emoji = [ + { + "emoji": "🎨", + "entity": "🎨", + "code": ":art:", + "description": "Improve structure / format of the code.", + "name": "art" + }, + { + "emoji": "⚡️", + "entity": "⚡", + "code": ":zap:", + "description": "Improve performance.", + "name": "zap" + }, + { + "emoji": "🔥", + "entity": "🔥", + "code": ":fire:", + "description": "Remove code or files.", + "name": "fire" + }, + { + "emoji": "🐛", + "entity": "🐛", + "code": ":bug:", + "description": "Fix a bug.", + "name": "bug" + }, + { + "emoji": "🚑", + "entity": "🚑", + "code": ":ambulance:", + "description": "Critical hotfix.", + "name": "ambulance" + }, + { + "emoji": "✨", + "entity": "✨", + "code": ":sparkles:", + "description": "Introduce new features.", + "name": "sparkles" + }, + { + "emoji": "📝", + "entity": "📝", + "code": ":memo:", + "description": "Add or update documentation.", + "name": "memo" + }, + { + "emoji": "🚀", + "entity": "🚀", + "code": ":rocket:", + "description": "Deploy stuff.", + "name": "rocket" + }, + { + "emoji": "💄", + "entity": "&#ff99cc;", + "code": ":lipstick:", + "description": "Add or update the UI and style files.", + "name": "lipstick" + }, + { + "emoji": "🎉", + "entity": "🎉", + "code": ":tada:", + "description": "Begin a project.", + "name": "tada" + }, + { + "emoji": "✅", + "entity": "✅", + "code": ":white_check_mark:", + "description": "Add or update tests.", + "name": "white-check-mark" + }, + { + "emoji":"🍎", + "entity": "", + "code": ":apple:", + "description": "apple", + "name": "apple" + }, + { + "emoji":"🐳", + "entity": "", + "code": ":whale:", + "description": "whale", + "name": "whale" + }, + { + "emoji": "🔒", + "entity": "🔒", + "code": ":lock:", + "description": "Fix security issues.", + "name": "lock" + }, + { + "emoji": "🔖", + "entity": "🔖", + "code": ":bookmark:", + "description": "Release / Version tags.", + "name": "bookmark" + }, + { + "emoji": "🚨", + "entity": "🚨", + "code": ":rotating_light:", + "description": "Fix compiler / linter warnings.", + "name": "rotating-light" + }, + { + "emoji": "🚧", + "entity": "🚧", + "code": ":construction:", + "description": "Work in progress.", + "name": "construction" + }, + { + "emoji": "💚", + "entity": "💚", + "code": ":green_heart:", + "description": "Fix CI Build.", + "name": "green-heart" + }, + { + "emoji": "⬇️", + "entity": "⬇️", + "code": ":arrow_down:", + "description": "Downgrade dependencies.", + "name": "arrow-down" + }, + { + "emoji": "⬆️", + "entity": "⬆️", + "code": ":arrow_up:", + "description": "Upgrade dependencies.", + "name": "arrow-up" + }, + { + "emoji": "📌", + "entity": "📌", + "code": ":pushpin:", + "description": "Pin dependencies to specific versions.", + "name": "pushpin" + }, + { + "emoji": "👷", + "entity": "👷", + "code": ":construction_worker:", + "description": "Add or update CI build system.", + "name": "construction-worker" + }, + { + "emoji": "📈", + "entity": "📈", + "code": ":chart_with_upwards_trend:", + "description": "Add or update analytics or track code.", + "name": "chart-with-upwards-trend" + }, + { + "emoji": "♻️", + "entity": "♲", + "code": ":recycle:", + "description": "Refactor code.", + "name": "recycle" + }, + { + "emoji": "➕", + "entity": "➕", + "code": ":heavy_plus_sign:", + "description": "Add a dependency.", + "name": "heavy-plus-sign" + }, + { + "emoji": "➖", + "entity": "➖", + "code": ":heavy_minus_sign:", + "description": "Remove a dependency.", + "name": "heavy-minus-sign" + }, + { + "emoji": "🔧", + "entity": "🔧", + "code": ":wrench:", + "description": "Add or update configuration files.", + "name": "wrench" + }, + { + "emoji": "🔨", + "entity": "🔨", + "code": ":hammer:", + "description": "Add or update development scripts.", + "name": "hammer" + }, + { + "emoji": "🌐", + "entity": "🌐", + "code": ":globe_with_meridians:", + "description": "Internationalization and localization.", + "name": "globe-with-meridians" + }, + { + "emoji": "✏️", + "entity": "", + "code": ":pencil2:", + "description": "Fix typos.", + "name": "pencil2" + }, + { + "emoji": "📝", + "entity": "📝", + "code": ":pencil:", + "description": "Add or update documentation.", + "name": "pencil" + }, + { + "emoji": "💩", + "entity": "", + "code": ":poop:", + "description": "Write bad code that needs to be improved.", + "name": "poop" + }, + { + "emoji": "⏪", + "entity": "⏪", + "code": ":rewind:", + "description": "Revert changes.", + "name": "rewind" + }, + { + "emoji": "🔀", + "entity": "🔀", + "code": ":twisted_rightwards_arrows:", + "description": "Merge branches.", + "name": "twisted-rightwards-arrows" + }, + { + "emoji": "📦", + "entity": "F4E6;", + "code": ":package:", + "description": "Add or update compiled files or packages.", + "name": "package" + }, + { + "emoji": "👽", + "entity": "F47D;", + "code": ":alien:", + "description": "Update code due to external API changes.", + "name": "alien" + }, + { + "emoji": "🚚", + "entity": "F69A;", + "code": ":truck:", + "description": "Move or rename resources (e.g.: files, paths, routes).", + "name": "truck" + }, + { + "emoji": "📄", + "entity": "F4C4;", + "code": ":page_facing_up:", + "description": "Add or update license.", + "name": "page-facing-up" + }, + { + "emoji": "💥", + "entity": "💥", + "code": ":boom:", + "description": "Introduce breaking changes.", + "name": "boom" + }, + { + "emoji": "🍱", + "entity": "F371", + "code": ":bento:", + "description": "Add or update assets.", + "name": "bento" + }, + { + "emoji": "♿️", + "entity": "♿", + "code": ":wheelchair:", + "description": "Improve accessibility.", + "name": "wheelchair" + }, + { + "emoji": "💡", + "entity": "💡", + "code": ":bulb:", + "description": "Add or update comments in source code.", + "name": "bulb" + }, + { + "emoji": "🍻", + "entity": "🍻", + "code": ":beers:", + "description": "Write code drunkenly.", + "name": "beers" + }, + { + "emoji": "💬", + "entity": "💬", + "code": ":speech_balloon:", + "description": "Add or update text and literals.", + "name": "speech-balloon" + }, + { + "emoji": "🗃", + "entity": "🗃", + "code": ":card_file_box:", + "description": "Perform database related changes.", + "name": "card-file-box" + }, + { + "emoji": "🔊", + "entity": "🔊", + "code": ":loud_sound:", + "description": "Add or update logs.", + "name": "loud-sound" + }, + { + "emoji": "🔇", + "entity": "🔇", + "code": ":mute:", + "description": "Remove logs.", + "name": "mute" + }, + { + "emoji": "👥", + "entity": "👥", + "code": ":busts_in_silhouette:", + "description": "Add or update contributor(s).", + "name": "busts-in-silhouette" + }, + { + "emoji": "🚸", + "entity": "🚸", + "code": ":children_crossing:", + "description": "Improve user experience / usability.", + "name": "children-crossing" + }, + { + "emoji": "🏗", + "entity": "f3d7;", + "code": ":building_construction:", + "description": "Make architectural changes.", + "name": "building-construction" + }, + { + "emoji": "📱", + "entity": "📱", + "code": ":iphone:", + "description": "Work on responsive design.", + "name": "iphone" + }, + { + "emoji": "🤡", + "entity": "🤡", + "code": ":clown_face:", + "description": "Mock things.", + "name": "clown-face" + }, + { + "emoji": "🥚", + "entity": "🥚", + "code": ":egg:", + "description": "Add or update an easter egg.", + "name": "egg" + }, + { + "emoji": "🙈", + "entity": "bdfe7;", + "code": ":see_no_evil:", + "description": "Add or update a .gitignore file.", + "name": "see-no-evil" + }, + { + "emoji": "📸", + "entity": "📸", + "code": ":camera_flash:", + "description": "Add or update snapshots.", + "name": "camera-flash" + }, + { + "emoji": "⚗", + "entity": "📸", + "code": ":alembic:", + "description": "Perform experiments.", + "name": "alembic" + }, + { + "emoji": "🔍", + "entity": "🔍", + "code": ":mag:", + "description": "Improve SEO.", + "name": "mag" + }, + { + "emoji": "🏷️", + "entity": "🏷", + "code": ":label:", + "description": "Add or update types.", + "name": "label" + }, + { + "emoji": "🌱", + "entity": "🌱", + "code": ":seedling:", + "description": "Add or update seed files.", + "name": "seedling" + }, + { + "emoji": "🚩", + "entity": "🚩", + "code": ":triangular_flag_on_post:", + "description": "Add, update, or remove feature flags.", + "name": "triangular-flag-on-post" + }, + { + "emoji": "🥅", + "entity": "🥅", + "code": ":goal_net:", + "description": "Catch errors.", + "name": "goal-net" + }, + { + "emoji": "💫", + "entity": "💫", + "code": ":dizzy:", + "description": "Add or update animations and transitions.", + "name": "animation" + }, + { + "emoji": "🗑", + "entity": "🗑", + "code": ":wastebasket:", + "description": "Deprecate code that needs to be cleaned up.", + "name": "wastebasket" + }, + { + "emoji": "🛂", + "entity": "🛂", + "code": ":passport_control:", + "description": "Work on code related to authorization, roles and permissions.", + "name": "passport-control" + }, + { + "emoji": "🩹", + "entity": "🩹", + "code": ":adhesive_bandage:", + "description": "Simple fix for a non-critical issue.", + "name": "adhesive-bandage" + } + ] + + export function getEmoji(code){ + let filter = emoji.filter(i=>i.code === code); + return filter.length>0?filter[0].emoji:code; + } diff --git a/src/forge/SecuritySetting/Index.jsx b/src/forge/SecuritySetting/Index.jsx index 8e697e0a..4b0e20bc 100644 --- a/src/forge/SecuritySetting/Index.jsx +++ b/src/forge/SecuritySetting/Index.jsx @@ -90,7 +90,7 @@ function Index(props){
    • 个人信息
    • -1 ?"active":""}>基本资料
    • -
    • -1 || pathname.indexOf("/settings/password")>-1 || pathname.indexOf("/settings/cancel")>-1) ?"active":""}>账号管理
    • +
    • -1 || pathname.indexOf("/settings/phone")>-1 || pathname.indexOf("/settings/password")>-1 || pathname.indexOf("/settings/cancel")>-1) ?"active":""}>账号管理
    {notice_url &&
    • 消息通知
    • @@ -153,6 +153,12 @@ function Index(props){ )} > + ( + + )} + > ( diff --git a/src/forge/users/Material/Base.jsx b/src/forge/users/Material/Base.jsx index aebe9617..8047eb24 100644 --- a/src/forge/users/Material/Base.jsx +++ b/src/forge/users/Material/Base.jsx @@ -52,11 +52,19 @@ export default Form.create()( return(
      + + {getFieldDecorator("phone",{ + rules:[{required:true,message:"请输入邮箱账号"}] + })( + + )} + + 更改手机号 {getFieldDecorator("email",{ rules:[{required:true,message:"请输入邮箱账号"}] })( - + )} 更改邮箱 diff --git a/src/forge/users/Material/Index.jsx b/src/forge/users/Material/Index.jsx index b0d123e4..bcd84e40 100644 --- a/src/forge/users/Material/Index.jsx +++ b/src/forge/users/Material/Index.jsx @@ -18,6 +18,9 @@ function Index(props){ }else{ setKey("1"); switch(pathname){ + case '/settings/phone': + setType('3'); + break; case '/settings/emails': setType('0'); break; @@ -37,6 +40,7 @@ function Index(props){ {key === "0" ? 基本资料 : + {props.history.push('/settings/phone')}}>手机号管理 {props.history.push('/settings/emails')}}>邮箱管理 {props.history.push('/settings/password')}}>密码管理 {props.history.push('/settings/cancel')}}>账号注销 diff --git a/src/forge/users/Material/Password.jsx b/src/forge/users/Material/Password.jsx index 694dee21..c2dda19c 100644 --- a/src/forge/users/Material/Password.jsx +++ b/src/forge/users/Material/Password.jsx @@ -6,6 +6,7 @@ import Axios from 'axios'; import img1 from '../../Images/personalInfo3.png'; import { setmiyah } from '../../../common/Component'; import { useEffect } from 'react'; +import Phone from './Phone'; export default Form.create()( forwardRef((props)=>{ @@ -239,7 +240,8 @@ export default Form.create()( // type: 0邮箱管理 1密码管理 2账号注销 return( - {type === '0' ?
      + {type === '0' ? +
      更改邮箱后,您在GitLink 的登录账号、接收通知的邮件地址将同步变更。请谨慎更改!
      现邮箱地址{current_user && current_user.email}
      更改邮箱
      @@ -286,7 +288,9 @@ export default Form.create()( -
      : type === '1' ?
      +
      : + type === '1' ? + {getFieldDecorator("old_password",{ rules:[ @@ -326,17 +330,21 @@ export default Form.create()( - :
      -
      请您谨慎操作,注销后帐号内所有数据都会被清空,且无法恢复帐号!
      -
      - GitLink目前提供邮件渠道帐号注销服务。如需注销帐号,请通过发送邮件注销申请邮件到 gitlink@ccf.org.cn
      - 相关注意事项如下:
      - 必须使用要注销的 GitLink 帐号所绑定的邮箱地址发送邮件。 - 发送注销申请邮件之前确认帐号下无创建/加入组织,帐号名下无仓库信息。 - 邮件标题: 注销 GitLink 帐号,邮件正文请注明要注销帐号的邮箱和昵称。 - 发送邮件后,我们会积极处理,请耐心等候我们的邮件回复。 + + : type === '2' ? +
      +
      请您谨慎操作,注销后帐号内所有数据都会被清空,且无法恢复帐号!
      +
      + GitLink目前提供邮件渠道帐号注销服务。如需注销帐号,请通过发送邮件注销申请邮件到 gitlink@ccf.org.cn
      + 相关注意事项如下:
      + 必须使用要注销的 GitLink 帐号所绑定的邮箱地址发送邮件。 + 发送注销申请邮件之前确认帐号下无创建/加入组织,帐号名下无仓库信息。 + 邮件标题: 注销 GitLink 帐号,邮件正文请注明要注销帐号的邮箱和昵称。 + 发送邮件后,我们会积极处理,请耐心等候我们的邮件回复。 +
      -
      } + : + } {setVisible(false)}} diff --git a/src/forge/users/Material/Phone.jsx b/src/forge/users/Material/Phone.jsx new file mode 100644 index 00000000..8eb78ae2 --- /dev/null +++ b/src/forge/users/Material/Phone.jsx @@ -0,0 +1,233 @@ +import React , { forwardRef, useState } from 'react'; +import { Form , Input , Button, message } from 'antd'; +import Modals from '../../Component/PublicModal/Index'; +import { AlignCenter } from '../../Component/layout'; +import img1 from '../../Images/personalInfo3.png'; +import { setmiyah } from '../../../common/Component'; +import Axios from 'axios'; + + +export default Form.create()( + forwardRef((props)=>{ + const { getFieldDecorator, validateFields, resetFields, getFieldsValue } = props && props.form; + const { current_user, resetUserInfo} = props; + const [ passMap, setPassMap] = useState({logpassword: undefined, phone: undefined, mescode: undefined}); + const [ countDown, setCountDown] = useState(undefined); + const [ phoneValue, setphoneValue] = useState(undefined); + const [ visible, setVisible] = useState(false); + + // 校验用户密码是否正确 + function checkPsd(rule, value, callback){ + const map = passMap; + if(value){ + current_user && Axios.post(`/v1/${current_user.login}/check_password.json`,{ + password: value + }).then(res=>{ + if(res && !res.data.status){ + map.logpassword = value; + setPassMap(map); + callback(); + }else{ + map.logpassword = undefined; + setPassMap(map); + callback(res.data.message); + } + }) + }else{ + map.logpassword = undefined; + setPassMap(map); + callback(); + } + } + // 校验用户填写验证码是否正确 + function checkCode(rule, value, callback){ + const map = passMap; + const {phone, logpassword} = getFieldsValue(); + if(!phone){ + callback("请先输入手机号"); + } + if(!logpassword){ + callback("请先输入登录密码"); + } + if(value){ + current_user && value && value.length > 4 && Axios.post(`/v1/${current_user.login}/check_phone_verify_code.json`,{ + code_type: 4, + phone: phoneValue, + code: value + }).then(res=>{ + if(res && !res.data.status){ + map.mescode = value; + setPassMap(map); + callback(); + }else{ + map.mescode = undefined; + setPassMap(map); + callback(res.data.message); + } + }) + }else{ + map.mescode = undefined; + setPassMap(map); + callback(); + } + } + // 校验用户手机号是否正确 + function checkPhone(rule, value, callback){ + const map = passMap; + if(value){ + if(/^([1][3456789])\d{9}$/.test(value)){ + current_user && Axios.get(`/accounts/valid_email_and_phone.json`,{ + params: { + login: value, + type: 3 + } + }).then(res=>{ + if(res && !res.data.status){ + map.phone = value; + setPassMap(map); + setphoneValue(value); + callback(); + }else{ + setphoneValue(undefined); + map.phone = undefined; + setPassMap(map); + callback(res.data.message); + } + }) + }else{ + map.phone = undefined; + setPassMap(map); + callback("请输入正确的手机号"); + } + }else{ + setphoneValue(undefined); + map.phone = undefined; + setPassMap(map); + callback(); + } + } + + //获取验证码 + function getCaptcha() { + // 给用户发送邮件https://testforgeplus.trustie.net/api/accounts/get_verification_code.json + current_user && Axios.get(`/accounts/get_verification_code`,{params: { + type: 3, + login: phoneValue, + smscode: setmiyah(phoneValue) + }}).then(res=>{ + if(res && !res.data.status){ + message.success('发送成功') + } + }) + // 获取验证码 + startCountDown(); + } + // 开始倒计时 + function startCountDown(){ + let countDownNum = 60; + const timer = setInterval(() => { + countDownNum -= 1; + setCountDown(countDownNum); + if(countDownNum <= -1){ + clearInterval(timer); + setCountDown(undefined) + } + }, 1000); + } + + function confirmUpdatePhone(){ + validateFields((error,values)=>{ + if(!error){ + setVisible(true); + } + }) + } + + function updateEmailOrPsd(){ + const {mescode, phone, logpassword} = getFieldsValue(); + if(mescode && phone && logpassword){ + current_user && Axios.patch(`/v1/${current_user.login}/update_phone.json`,{ + code:mescode, phone, password:logpassword + }).then(res=>{ + if(res && !res.data.status){ + setPassMap({logpassword: undefined, phone: undefined, code: undefined}); + resetFields(); + resetUserInfo(); + setVisible(false); + message.success('更新成功'); + }else{ + setVisible(false); + message.error(res.data.message || '更新失败'); + } + }) + } + } + + return( +
      + {setVisible(false)}} + title={'更改手机号'} + btn={ +
      + + +
      + } + > +
      + + 确认更改手机号? +

      更改手机号后,您在GitLink的登录账号将同步变更。请再次确认。

      +
      +
      +
      更改手机号后,您在GitLink 的登录账号将同步变更。请谨慎更改!
      + {current_user && current_user.phone &&
      现手机号码{current_user.phone}
      } +
      更改手机号
      +
      + + {getFieldDecorator("logpassword",{ + rules:[ + {required:true,message:"请输入登录密码"}, + {validator:(rule, value, callback)=>checkPsd(rule, value, callback)} + ], + validateTrigger:"onBlur", + })( + + )} + + + {getFieldDecorator("phone",{ + rules:[ + {required:true,message:"请输入新手机号码"}, + {validator:(rule, value, callback)=>checkPhone(rule, value, callback)} + ], + validateTrigger:"onBlur", + })( + + )} + +
      + + {getFieldDecorator("mescode",{ + rules:[ + {required:true,message:"请输入短信验证码"}, + {validator:(rule, value, callback)=>checkCode(rule, value, callback)} + ], + validateTrigger:"onBlur", + })( + + )} + + {countDown ? : } +
      + + + + +
      +
      + ) + }) +) \ No newline at end of file