浏览代码

[add]join discord

wenliming 3 年之前
父节点
当前提交
d8272ba5e4

+ 5 - 1
src/entry/background.js

@@ -12,7 +12,8 @@ import {
     hideBadge,
     setMessageCount,
     getMessageInfo,
-    readTaskAllMsg
+    readTaskAllMsg,
+    discordLoginCode
 } from "@/logic/background/twitter";
 
 //加载bg.js 执行
@@ -31,6 +32,9 @@ chrome.runtime.onConnect.addListener(function (port) {
             case "CONTENT_TWITTER_SHORT_LINK":
                 twitterShortUrl(res.url)
                 break
+            case "CONTENT_SEND_DISCORD_AUTH_CODE":
+                discordLoginCode(res.code);
+                break
         }
     });
     if (port.name === "popup") {

+ 1 - 0
src/http/configAPI.js

@@ -24,3 +24,4 @@ export const logAPIUrl = logApi[process.env.NODE_ENV] + '/log-center'
 
 export const pageUrl = page[process.env.NODE_ENV] 
 
+export const discordAuthRedirectUri = `${pageUrl}/auth/discordCallback`;

+ 17 - 0
src/http/discordApi.js

@@ -0,0 +1,17 @@
+import { service } from "./request";
+
+export function discordAuthUrl(params) {
+    return service({
+        url: `/openapi/discord/authorize`,
+        method: "post",
+        data: params,
+    });
+}
+
+export function getInviteGuildInfo(params) {
+    return service({
+        url: `/openapi/discord/getInviteGuildInfo`,
+        method: "post",
+        data: params,
+    });
+}

+ 37 - 0
src/logic/background/fetch/twitter.js

@@ -146,4 +146,41 @@ export async function fetchReadTaskAllMsg(params = {}) {
                 reject(error);
             });
     })
+}
+
+
+export async function getDiscordUserInfo(params = {}) {
+    let storage_mid = await getChromeStorage('mid') || ''
+    const { accessToken: token = '', uid = '' } = await getChromeStorage('userInfo') || {}
+    const { mid } = storage_mid || {};
+    return new Promise(function (resolve, reject) {
+        if(!token) {
+            resolve({});
+        }
+        let _url = `${baseAPIUrl}/openapi/discord/token`
+        fetch(_url, {
+            method: 'POST', 
+            headers: {
+                'Content-Type': 'application/json',
+            },
+            body: JSON.stringify({
+                "baseInfo": {
+                    appVersionCode,
+                    mid,
+                    machineCode: mid,
+                    token: token,
+                    uid,
+                    loginUid: uid,
+                    appType:1,
+                },
+                "params": params
+            }),
+        }).then(response => response.json())
+            .then(data => {
+                resolve(data);
+            })
+            .catch((error) => {
+                reject(error);
+            });
+    })
 }

+ 26 - 2
src/logic/background/twitter.js

@@ -1,7 +1,7 @@
-import { fetchTtwitterRequestToken, fetchTwitterLogin, fetchTwitterShortUrl, fetchAllMessageInfo, fetchReadTaskAllMsg } from '@/logic/background/fetch/twitter.js'
+import { fetchTtwitterRequestToken, fetchTwitterLogin, fetchTwitterShortUrl, fetchAllMessageInfo, fetchReadTaskAllMsg, getDiscordUserInfo } from '@/logic/background/fetch/twitter.js'
 import { LANDING_PAGE, LANDING_PAGE_MID, setChromeStorage, setChromeCookie, getChromeCookie ,getChromeStorage, removeChromeCookie} from '@/uilts/chromeExtension.js'
 import { guid } from '@/uilts/help.js'
-import { pageUrl } from '@/http/configAPI'
+import { pageUrl, discordAuthRedirectUri } from '@/http/configAPI'
 
 let authToken = ''
 export function twitterPinLoginToken() {
@@ -60,6 +60,30 @@ export function twitterPinLoginCode(port,code) {
 
 }
 
+export function discordLoginCode(code) {
+    chrome.tabs.query({}, (tab) => {
+        for (let i in tab) {
+            if (tab[i].url.indexOf('denetme.net/auth/discordCallback') > -1) {
+                chrome.tabs.remove(tab[i].id)
+            }
+        }
+    })
+    console.log(code)
+    // 发送请求
+    getDiscordUserInfo({
+        authCode: code,
+        redirectUrl: discordAuthRedirectUri
+    }).then(res => {
+        if (res.code == 0) {
+            setTimeout(() => {
+                sendActivetabMessage({
+                    actionType: 'BACK_DISCORD_LOGIN_SUCCESS'
+                });
+            })
+        }
+    })
+}
+
 export function twitterShortUrl(url) {
     return new Promise(function (resolve, reject) {
         fetchTwitterShortUrl(url).then(res => {

+ 14 - 0
src/logic/content/twitter.js

@@ -1,6 +1,7 @@
 import { getChromeStorage, setChromeStorage } from '@/uilts/chromeExtension.js'
 import { throttle } from '@/uilts/help'
 import { srcPublishSuccess } from '@/http/publishApi'
+import { discordAuthRedirectUri } from '@/http/configAPI'
 import Report from "@/log-center/log"
 
 
@@ -16,6 +17,16 @@ function twitterPinLogin(port) {
     }
 }
 
+function getDiscordAuthCode(port) {
+    if (window.location.href.indexOf(discordAuthRedirectUri) > -1) {
+        const urlParams = new URLSearchParams(window.location.search);
+        const code = urlParams.get('code');
+        if (code) {
+            port.postMessage({ state: 'CONTENT_SEND_DISCORD_AUTH_CODE', code })
+        }
+    }
+};
+
 
 
 /**
@@ -715,6 +726,9 @@ export function initExecuteScript(port,changes) {
 
 
 export function init(port) {
+    if (window.location.href.indexOf(discordAuthRedirectUri) > -1) {
+        getDiscordAuthCode(port);
+    }
     if (window.location.href.indexOf('twitter.com') < 0) {
         return
     }

+ 4 - 1
src/manifest.json

@@ -19,7 +19,10 @@
         {
             "matches": [
                 "https://*.twitter.com/*",
-                "https://twitter.com/*"
+                "https://twitter.com/*",
+                "*://testh5.denetme.net/*",
+                "*://h5.denetme.net/*",
+                "*://preh5.denetme.net/*"
             ],
             "run_at": "document_start",
             "js": [

+ 3 - 3
src/view/iframe/publish/components/follow-input.vue

@@ -255,7 +255,7 @@ const onUserMouseLeave = (params, index) => {
         width: 100%;
         display: flex;
         flex-wrap: wrap;
-        padding: 0px 0 10px 18px;
+        padding: 0px 0 4px 18px;
         box-sizing: border-box;
 
         .icon-add{
@@ -278,7 +278,7 @@ const onUserMouseLeave = (params, index) => {
             position: relative;
             margin-right: 10px;
             background-color: #fff;
-            margin-top: 10px;
+            margin-top: 4px;
 
             .icon-del {
                 width: 18px;
@@ -375,7 +375,7 @@ const onUserMouseLeave = (params, index) => {
         .icon-add-wrapper {
             display: flex;
             align-items: center;
-            margin-top: 14px;
+            margin-top: 10px;
         }
     }
 </style>

+ 107 - 24
src/view/iframe/publish/give-dialog.vue

@@ -168,27 +168,39 @@
                                     v-for="(item, index) in formList"
                                     :key="index"
                                 >
-                                    <div class="label">
-                                        <img
-                                            class="icon"
-                                            :src="item.icon"
-                                        />
-                                        {{ item.label }}
-                                    </div>
-                                    <div
-                                        class="control"
-                                        v-if="item.nodeType == 'textarea'"
-                                    >
-                                        <follow-input
-                                            :isAddSelf="!isBack"
-                                            :atUserList="atUserList"
-                                            @addUser="addFollowUser"
-                                            @setUser="setFollowUser"
-                                            @delUser="delFollowUser"
-                                        ></follow-input>
+                                    <div class="item-left">
+                                        <div class="label">
+                                            <img
+                                                class="icon"
+                                                :src="item.icon"
+                                            />
+                                            {{ item.label }}
+                                        </div>
+                                        <div
+                                            class="control"
+                                            v-if="item.nodeType == 'textarea'"
+                                        >
+                                            <follow-input
+                                                :isAddSelf="!isBack"
+                                                :atUserList="atUserList"
+                                                @addUser="addFollowUser"
+                                                @setUser="setFollowUser"
+                                                @delUser="delFollowUser"
+                                            ></follow-input>
+                                        </div>
+                                        <div
+                                            class="control"
+                                            v-if="item.nodeType == 'input'"
+                                        >
+                                            <input v-model="item.text" 
+                                                placeholder="Enter link address"
+                                                class="discord-address" 
+                                                @input="onIptDiscordAddress($event, index)"
+                                                @blur="onBlurDiscordAddress($event, index)" />
+                                        </div>
                                     </div>
                                     <el-switch
-                                        v-if="item.type == 2"
+                                        v-if="item.type == 2 || item.type == 7"
                                         v-model="item.checked"
                                     />
                                     <img
@@ -298,6 +310,7 @@
 <script setup>
 import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick } from "vue";
 import { postPublish, verifyPaypalResult, syncChainTokenRechargeRecord, getCurrencyInfoByCode } from "@/http/publishApi";
+import { getInviteGuildInfo } from "@/http/discordApi";
 import { payCalcFee, getPayConfig } from "@/http/pay";
 import { getFrontConfig } from "@/http/account";
 import {setChromeStorage, getChromeStorage} from "@/uilts/chromeExtension"
@@ -332,7 +345,7 @@ let paypalHtml = ref("");
 let publishRes = reactive({});
 
 //弹窗是否展示
-let visible = ref(false);
+let visible = ref(true);
 
 //弹窗高度
 let dialogHeight = ref(680);
@@ -448,6 +461,14 @@ let formList = reactive([
         type: 2,
         checked: true,
     },
+    {
+        label: "Join Discord",
+        icon: require("@/assets/svg/icon-like.svg"),
+        nodeType: "input",
+        text: '',
+        type: 7,
+        checked: true,
+    },
 ]);
 
 const props = defineProps({
@@ -720,7 +741,10 @@ const submitRequest = async () => {
             let relatedUsers = formList[i]["text"];
             item.relatedUsers = relatedUsers;
             finishConditions.push(item);
-        } else if (formList[i]["checked"]) {
+        } else  if (formList[i]["checked"] && formList[i]["text"] && formList[i]["type"] == 7) {
+            item.bizData = JSON.stringify({inviteUrl: formList[i]["text"]});
+            finishConditions.push(item);
+        } else  if (formList[i]["checked"]) {
             finishConditions.push(item);
         }
     }
@@ -974,6 +998,45 @@ const onIptSetErrorTxt = () => {
     } 
 }
 
+const onIptDiscordAddress = (e, index) => {
+    let val = formList[index].text;
+
+}
+
+const onBlurDiscordAddress = (e, index) => {
+    let val = formList[index].text;
+
+    getInviteGuildInfoa(val);
+}
+
+const checkInviteUrl = (inviteUrl) => {
+    let flag = true;
+    const INVITE_URL_PREFIX = 'https://discord.gg/';
+    const INVITE_URL_PREFIX_OLD = 'https://discord.com/invite/';
+
+    if(inviteUrl == INVITE_URL_PREFIX || inviteUrl == INVITE_URL_PREFIX_OLD || 
+        (!inviteUrl.startsWith(INVITE_URL_PREFIX) && !inviteUrl.startsWith(INVITE_URL_PREFIX_OLD))) {
+        flag = false;
+    }
+
+    return flag;
+}
+
+const getInviteGuildInfoa = (inviteUrl) => {
+    let validata = checkInviteUrl(inviteUrl);
+    console.log(validata, 'validata')
+    if(!validata) return;
+    getInviteGuildInfo({
+        params: {
+            inviteUrl
+        }
+    }).then(res => {
+        if(res.code == 0) {
+
+        }
+    })
+}
+
 /**
  * 获取支付配置(paypalClientId)
  */
@@ -1430,9 +1493,15 @@ onMounted(() => {
                             justify-content: space-between;
                             margin: 0 16px;
                             border-bottom: 1px solid #ececec;
+                            padding: 8px 0;
+                            box-sizing: border-box;
+                            
+                            .item-left {
+                                display: flex;
+                            }
 
                             .label {
-                                min-width: 88px;
+                                min-width: 76px;
                                 display: flex;
                                 align-items: center;
                                 font-size: 15px;
@@ -1444,10 +1513,24 @@ onMounted(() => {
                             }
 
                             .control {
-                                width: 100%;
-                                min-height: 50px;
+                                min-width: 280px;
                                 margin-left: 18px;
                                 box-sizing: border-box;
+                                border-left: 1px solid #ECECEC;
+
+                                .discord-address {
+                                    border: none;
+                                    outline: none;
+                                    color: #1D9BF0;
+                                    font-weight: 500;
+                                    font-size: 14px;
+                                    width: 100%;
+                                    height: 34px;
+                                    padding-left: 15px;
+                                }
+                                .discord-address::placeholder {
+                                    color: #c5c5c5;
+                                }
                             }
                         }
                         .form-item:last-child {

+ 79 - 1
src/view/iframe/red-packet/red-packet.vue

@@ -60,6 +60,15 @@
             <div v-else class="btn" @click="clickRetweetBtn">Retweet</div>
           </template>
         </div>
+        <div class="item">
+            <img :src="require('@/assets/svg/icon-like.svg')" alt />
+            <div class="item-content">
+              <div class="item-title">Join Discord</div>
+            </div>
+            <div @click="joinDiscord">
+              join
+            </div>
+        </div>
       </div>
       <div class="people" @click="clickRoad">
         <div class="txt">
@@ -242,15 +251,19 @@ export default {
 <script setup>
 import { onMounted, reactive } from "vue";
 import { getPostDetail, getRedPacket, finishRedPacket, oneKeyLike, oneKeyReTweet, oneKeyFollow, getTaskDetail, getReceivedList } from '@/http/redPacket.js'
-import { getQueryString } from '@/uilts/help.js'
+import { getQueryString, guid } from '@/uilts/help.js'
 import { message } from 'ant-design-vue';
 import FontAmount from '@/view/components/font-amount.vue'
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
 import Report from "@/log-center/log"
 import { srcPublishSuccess } from '@/http/publishApi'
+import { discordAuthUrl } from '@/http/discordApi'
+import { discordAuthRedirectUri } from '@/http/configAPI'
 
 var moment = require('moment');
 
+let joinDiscordActionState = 'default'; //authAndJoinIng  joinIng 
+
 let data = reactive({
   status: '',
   loading_show: false,
@@ -514,6 +527,8 @@ function showLastTwoPlace(n) {
 }
 
 function init() {
+  onRuntimeMsg();
+  onPageVisbile();
   getPostDetail({
     params: {
       postId: data.postId
@@ -929,6 +944,69 @@ function clickRoad() {
     businessType: Report.businessType.pageView
   });
 }
+
+function onPageVisbile() {
+  document.addEventListener('visibilitychange', function() {
+      let isHidden = document.hidden;
+      console.log('joinDiscordActionState', joinDiscordActionState);
+      if (!isHidden) {
+        // 如果上次的状态是 joinIng 检查他是否真正join
+        if(joinDiscordActionState == 'joinIng') {
+          // 请求接口 加入之后设置
+          joinDiscordActionState = 'default';
+        }
+      } 
+  });
+}
+
+function onRuntimeMsg() {
+  chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
+    sendResponse('');
+      switch (req.actionType) {
+          case 'BACK_DISCORD_LOGIN_SUCCESS':
+            discordLoginSuccess();
+            break;
+      }
+  })
+}
+
+function joinDiscord() {
+  // 1、判断之前有没有授权
+  //没有授权
+  discordAuth();
+}
+
+function discordAuth() {
+    let state = guid();
+    discordAuthUrl({
+        params : {
+            redirectUrl: discordAuthRedirectUri,
+            state
+        }
+    }).then(res => {
+        if(res.code == 0) {
+            let {authorizeUrl = ''} = res.data || {};
+            if(authorizeUrl) {
+              joinDiscordActionState = 'authAndJoinIng'; 
+              window.open(authorizeUrl)
+            }
+        }
+    })
+}
+
+
+function discordLoginSuccess() {
+  console.log('discordloginSuccess');
+  // 如果是join 并授权 回来后默认打开 邀请链接
+  if(joinDiscordActionState == 'authAndJoinIng') {
+    joinDiscordActionState = 'joinIng';
+    let url = 'https://discord.com/invite/ZUEgYt7hHb';
+    window.open(url);
+  } 
+}
+
+
+
 </script>
  
 <style  lang="scss">