CodePreviewIndexNew.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <template>
  2. <div class="platform-sdk-code rounded-8px lg:w-600px">
  3. <div class="relative flex items-end h-48px bg-black rounded-t-8px">
  4. <div
  5. v-for="(device, index) in devices"
  6. :key="index"
  7. :class="[
  8. 'item',
  9. 'relative',
  10. 'flex',
  11. 'items-center',
  12. 'justify-center',
  13. 'h-48px',
  14. 'w-110px',
  15. 'font-600',
  16. 'cursor-pointer',
  17. device === currentPlatform ? 'active-menu-bg text-white h-52px pt-4px <lg:min-w-110px' : 'text-[#AAAEB7]',
  18. { active: device === currentPlatform },
  19. ]"
  20. @click="currentPlatform = device"
  21. >
  22. <component :is="device" />
  23. <span class="inline-block ml-3px text-14px leading-20px" :class="device === currentPlatform ? '' : '<lg:hidden'">{{ device }}</span>
  24. </div>
  25. </div>
  26. <div class="relative flex flex-1 flex-col text-left rounded-b-8px overflow-hidden">
  27. <div class="pl-20px pr-16px pt-14px pb-30px bg-[#27293B] <lg:pb-14px">
  28. <div class="options">
  29. <span
  30. v-for="(value, key, index) in code[currentPlatform]"
  31. :key="key"
  32. class="code-tab inline-block px-6px py-2px rounded-4px text-sm font-600 text-[#FFFFFFA6]"
  33. :class="[
  34. 'relative',
  35. currentLanguageIndex === index ? '!text-white bg-[#545C6A]' : 'hover:text-white active:text-[#FFFFFFD9]',
  36. index && 'ml-16px',
  37. 'text-sm',
  38. 'cursor-pointer'
  39. ]"
  40. @click="changeLanguage(key, index)"
  41. >{{ key }}</span>
  42. </div>
  43. <div class="flex-grow-1 h-340px mt-12px overflow-auto <lg:(mt-22px h-350px)">
  44. <div v-for="(item, index) in code[currentPlatform][currentLanguage]" :key="index" class="flex">
  45. <div class="mr-12px min-w-14px text-14px leading-24px text-[#94969D] text-right">{{ index + 1 }}</div>
  46. <pre>
  47. <code
  48. ref="code-content"
  49. class="block text-sm text-white lg:whitespace-pre-wrap"
  50. v-html="item"
  51. ></code>
  52. </pre>
  53. </div>
  54. </div>
  55. <transition>
  56. <span
  57. v-show="copied"
  58. class="toast absolute bottom-60px right-10px opacity-100 py-5px px-8px text-sm rounded-4px bg-[#CCCCCC] transition-all duration-300"
  59. >复制</span>
  60. </transition>
  61. <span class="absolute bottom-20px right-20px flex justify-center items-center w-36px h-36px cursor-pointer bg-[#4a4b5a] text-[#C4C4C4] rounded-full hover:text-[#FFFFFF] <lg:bottom-18px">
  62. <Copy
  63. @click="copy(code[currentPlatform][currentLanguage])"
  64. />
  65. </span>
  66. </div>
  67. </div>
  68. </div>
  69. </template>
  70. <script>
  71. import { ResizeObserver } from '@juggle/resize-observer'
  72. import clipboard from 'copy-to-clipboard'
  73. import iOS from '~/assets/images/icons/apple_i.svg?inline'
  74. import Mac from '~/assets/images/icons/macos_i.svg?inline'
  75. import Android from '~/assets/images/icons/android_i.svg?inline'
  76. import Windows from '~/assets/images/icons/windows_i.svg?inline'
  77. import Web from '~/assets/images/icons/web_i.svg?inline'
  78. import Copy from '~/assets/images/icons/copy_i.svg?inline'
  79. import Guides from '~/assets/images/icons/guides.svg?inline'
  80. import Contact from '~/assets/images/icons/contact.svg?inline'
  81. import Arrow from '~/assets/images/icons/arrow.svg?inline'
  82. import Trial from '~/assets/images/icons/trial.svg?inline'
  83. import Linux from '~/assets/images/icons/linux.svg?inline'
  84. import ArrowRight from '~/assets/images/icons/ArrowRight.svg?inline'
  85. import ArrowRightActive from '~/assets/images/icons/ArrowRightActive.svg?inline'
  86. export default {
  87. components: {
  88. iOS,
  89. Mac,
  90. Android,
  91. Windows,
  92. Web,
  93. Copy,
  94. Guides,
  95. Contact,
  96. Arrow,
  97. Trial,
  98. Linux,
  99. ArrowRight,
  100. ArrowRightActive
  101. },
  102. props: {
  103. platform: {
  104. default: 'iOS'
  105. },
  106. language: {
  107. default: 'Objective-C'
  108. },
  109. languageIndex: {
  110. default: 0
  111. },
  112. code: Object,
  113. devices: Array
  114. },
  115. data () {
  116. return {
  117. currentPlatform: this.platform,
  118. currentLanguage: this.language,
  119. currentLanguageIndex: this.languageIndex,
  120. copied: false,
  121. timer: null,
  122. showOptions: false,
  123. width: 929,
  124. minHidden: false,
  125. active: false
  126. }
  127. },
  128. watch: {
  129. code () {
  130. if (!this.code.Web) {
  131. this.currentPlatform = 'iOS'
  132. this.currentLanguage = 'Objective-C'
  133. }
  134. },
  135. currentPlatform (value, oldValue) {
  136. if (value === oldValue) {
  137. return
  138. }
  139. this.currentLanguageIndex = 0
  140. switch (value) {
  141. case 'iOS':
  142. case 'Mac':
  143. this.currentLanguage = 'Objective-C'
  144. break
  145. case 'Android':
  146. this.currentLanguage = 'Java'
  147. break
  148. case 'Windows':
  149. this.currentLanguage = 'C# WPF'
  150. break
  151. case 'Web':
  152. this.currentLanguage = 'JavaScript'
  153. break
  154. case 'Linux':
  155. this.currentLanguage = 'CMD'
  156. break
  157. }
  158. }
  159. },
  160. mounted () {
  161. document.addEventListener('click', () => {
  162. if (this.showOptions) {
  163. this.showOptions = false
  164. }
  165. })
  166. const ro = new ResizeObserver((entries, observer) => {
  167. entries.forEach((entry, index) => {
  168. const { inlineSize: width } = entry.borderBoxSize[0]
  169. this.width = width
  170. })
  171. })
  172. ro.observe(document.body)
  173. },
  174. methods: {
  175. changeLanguage (language, index) {
  176. if (this.currentLanguage === language) {
  177. return
  178. }
  179. this.currentLanguage = language
  180. this.currentLanguageIndex = index
  181. },
  182. handlePlatformChange (platform, index) {
  183. if (platform === this.currentPlatform) {
  184. if (this.width < 930) {
  185. this.minHidden = !this.minHidden
  186. }
  187. return
  188. }
  189. this.minHidden = false
  190. this.currentPlatform = platform
  191. this.$nextTick(() => {
  192. window.scrollTo({
  193. left: 0,
  194. top: this.$refs.platform[index].offsetTop - 66
  195. })
  196. })
  197. },
  198. getGuidesUrl () {
  199. if (this.currentPlatform === 'Web') {
  200. return false
  201. } else {
  202. return '/guides/' + this.currentPlatform.toLowerCase()
  203. }
  204. },
  205. copy (content) {
  206. content = content.join('\n')
  207. content = content.replace(/<\/?.+?>/g, '')
  208. content = content.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/&quot;/g, '"')
  209. clipboard(content, {
  210. format: 'text/plain'
  211. })
  212. this.copied = true
  213. if (this.timer) {
  214. clearTimeout(this.timer)
  215. this.timer = null
  216. }
  217. this.timer = setTimeout(() => {
  218. this.copied = false
  219. }, 1500)
  220. }
  221. }
  222. }
  223. </script>
  224. <style lang="scss" scoped>
  225. .platform-sdk-code {
  226. box-shadow: 0px 2.31602px 27.0202px rgba(129, 149, 200, 0.18);
  227. }
  228. .item {
  229. svg {
  230. width: 20px;
  231. height: 20px;
  232. }
  233. &:first-child {
  234. width: 100px;
  235. &.active-menu-bg {
  236. background: url('~/assets/images/home/code_menu_first_bg.svg') no-repeat;
  237. }
  238. }
  239. &.active-menu-bg {
  240. background: url('~/assets/images/home/code_menu_bg.svg') no-repeat;
  241. }
  242. &:last-child {
  243. width: 100px;
  244. &.active-menu-bg {
  245. background: url('~/assets/images/home/code_menu_last_bg.svg') no-repeat;
  246. }
  247. }
  248. }
  249. .over-arrow::after {
  250. margin-top: -5px;
  251. border-color: transparent transparent #000 transparent;
  252. }
  253. .code-tab {
  254. &::after {
  255. content: '';
  256. position: absolute;
  257. left: 50%;
  258. transform: translateX(-50%);
  259. bottom: 0;
  260. display: block;
  261. width: 0;
  262. height: 2px;
  263. background-color: transparent;
  264. transition: width .3s;
  265. }
  266. &.active::after {
  267. width: calc(100% - 40px);
  268. background-color: #0097FF;
  269. }
  270. }
  271. .toast.v-enter, .toast.v-leave-to {
  272. opacity: 0;
  273. bottom: 50px;
  274. }
  275. pre {
  276. font-size: 0;
  277. code {
  278. font-family: Consolas, Helvetica;
  279. ::v-deep {
  280. .hljs-variable, .statement {
  281. color: #7B563D;
  282. }
  283. .hljs-string, .string {
  284. color: #C0402D;
  285. }
  286. .hljs-keyword, .keyword {
  287. color: #A0459F;
  288. }
  289. .hljs-title, .title {
  290. color: #367AAC;
  291. }
  292. .hljs-comment, .comment {
  293. color: #70A14F;
  294. }
  295. }
  296. }
  297. }
  298. .help::after {
  299. content: '';
  300. position: absolute;
  301. top: -19px;
  302. left: 0;
  303. display: block;
  304. width: 100%;
  305. height: 19px;
  306. background: linear-gradient(90deg, rgba(20, 96, 243, 0.9) 29.22%, rgba(255, 255, 255, 0.1) 100%);
  307. }
  308. .help{
  309. .todemo:hover{
  310. ::v-deep svg:nth-child(1){
  311. display: none;
  312. }
  313. ::v-deep svg:nth-child(2){
  314. display: flex;
  315. }
  316. }
  317. }
  318. @media screen and (max-width: 929px) {
  319. pre::-webkit-scrollbar{
  320. width: 6px;
  321. height: 6px;
  322. background-color: #27293B;
  323. }
  324. pre::-webkit-scrollbar-track{
  325. background-color: #27293B;
  326. }
  327. pre::-webkit-scrollbar-thumb{
  328. background-color: rgba(255, 255, 255, 0.3);
  329. border-radius: 4px;
  330. }
  331. pre::-webkit-scrollbar-corner {
  332. background-color: transparent;
  333. }
  334. .item.active-menu-bg {
  335. &:first-child {
  336. min-width: 100px;
  337. }
  338. &:last-child {
  339. min-width: 100px;
  340. }
  341. }
  342. }
  343. @media screen and (max-width: 374px) {
  344. .help > a:first-child.cn {
  345. margin-right: 0px;
  346. }
  347. .help > a:last-child.cn {
  348. margin-left: 0px;
  349. }
  350. }
  351. @media screen and (min-width: 1280px) {
  352. .item {
  353. &:last-child {
  354. width: 110px;
  355. &.active-menu-bg {
  356. background: url('~/assets/images/home/code_menu_bg.svg') no-repeat;
  357. }
  358. }
  359. }
  360. }
  361. </style>