diff --git a/CHANGELOG.md b/CHANGELOG.md index f21cc42..9ba202d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [0.0.4] 2022.10.10 + +- feat: Download picture. + ## [0.0.3] - feat: Favorite project. diff --git a/package.json b/package.json index ba04f72..1ba0f85 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "artstation", "displayName": "artstation", "description": "Artstation for VS Code", - "version": "0.0.3", + "version": "0.0.4", "engines": { "vscode": "^1.71.0" }, diff --git a/src/helper.ts b/src/helper.ts index e218063..d467235 100644 --- a/src/helper.ts +++ b/src/helper.ts @@ -1,6 +1,8 @@ import * as vscode from 'vscode'; import * as path from 'path'; import * as fs from 'fs'; +import * as url from 'url'; +import axios from 'axios'; export const getSourcePath = (context: vscode.ExtensionContext, relativePath: string): vscode.Uri => { const absPath = path.join(context.extensionPath, relativePath); @@ -85,3 +87,61 @@ export const getCookie = (cookie: string, name: string): string => { } return ''; }; + +export const downloadFile = async ( + url: string, + filePath: string, +): Promise => { + const response = await axios({ + url, + method: 'GET', + responseType: 'stream', + }); + if (response.status === 302) { + return downloadFile(response.headers.location as string, filePath); + } + if (response.status !== 200) { + throw new Error(`HTTP STATUS: ${response.status}`); + } + const file = fs.createWriteStream(filePath); + + return new Promise((resolve, reject) => { + file.on('finish', () => { + file.close(); + resolve(true); + }); + file.on('error', err => reject(err)); + + response.data.pipe(file); + }); +}; + +export const validWallpaperPath = (): boolean => { + const configure = vscode.workspace.getConfiguration('artstation'); + const wallpaperPath = configure.get('wallpaperPath') as string; + if (!wallpaperPath) { + vscode.window.showErrorMessage([ + 'Please set wallpaper save path.', + '请先设置壁纸保存路径', + ].join(' ')); + return false; + } + if (!fs.lstatSync(wallpaperPath).isDirectory()) { + vscode.window.showErrorMessage([ + 'Wallpaper save path is incorrect', + '壁纸保存路径不正确', + ].join(' ')); + return false; + } + return true; +}; + +export const getWallpaperPath = (imageUrl: string): string => { + const configure = vscode.workspace.getConfiguration('artstation'); + const wallpaperPath = configure.get('wallpaperPath') as string; + + const pathname = url.parse(imageUrl).pathname; + const basename = path.basename(pathname as string); + const filePath = path.join(wallpaperPath, `${randomString(5)}-${basename}`); + return filePath; +}; diff --git a/src/plugin/artstation.ts b/src/plugin/artstation.ts index ef5f887..688b6d2 100644 --- a/src/plugin/artstation.ts +++ b/src/plugin/artstation.ts @@ -5,7 +5,7 @@ import * as apis from './api'; import * as render from './render'; import { channelType, IMessage } from './model'; import { setWallpaper } from '../wallpaper'; -import { getLoadingPage } from '../helper'; +import { getLoadingPage, validWallpaperPath, downloadFile, getWallpaperPath } from '../helper'; import { SyncKeys } from '../constants'; dayjs.extend(relativeTime); @@ -44,6 +44,7 @@ export const artstation = (context: vscode.ExtensionContext) => { handleFollowing(panel, message); handleVotes(panel, message); handleSetWallpaper(context, message); + handleDownload(context, message); }, undefined, context.subscriptions); }; @@ -155,10 +156,10 @@ const handleSetWallpaper = async (context: vscode.ExtensionContext, message: IMe if (message.command !== 'wallpaper') { return; } - interface IPayload { + type IPayload = { url: string, for: string, - } + }; const answer = await vscode.window.showInformationMessage( 'Do you want to set it as the system wallpaper? 要设置成系统壁纸吗?', 'Yes', 'No', @@ -168,3 +169,21 @@ const handleSetWallpaper = async (context: vscode.ExtensionContext, message: IMe } setWallpaper(context, (message.payload as IPayload).url); }; + +const handleDownload = async (context: vscode.ExtensionContext, message: IMessage) => { + if (message.command !== 'download') { + return; + } + const valid = validWallpaperPath(); + if (!valid) { + return; + } + const filePath = getWallpaperPath(message.payload as string); + try { + await downloadFile(message.payload as string, filePath); + vscode.window.showInformationMessage('Download succeed. 下载成功'); + } catch (error) { + console.error(error); + vscode.window.showErrorMessage('Download failed. 下载失败'); + } +}; diff --git a/src/plugin/render.ts b/src/plugin/render.ts index 42632ee..a3698a6 100644 --- a/src/plugin/render.ts +++ b/src/plugin/render.ts @@ -131,7 +131,8 @@ export const renderAssetActions = (url: string): string => { } return `
- + +
`; }; diff --git a/src/wallpaper/index.ts b/src/wallpaper/index.ts index cc52254..4b63b8d 100644 --- a/src/wallpaper/index.ts +++ b/src/wallpaper/index.ts @@ -1,13 +1,11 @@ import * as vscode from 'vscode'; -import * as https from 'https'; import * as fs from 'fs'; import * as path from 'path'; -import * as url from 'url'; import * as os from 'os'; import * as wallpaper from 'wallpaper'; import * as macos from './macos'; import * as windows from './windows'; -import { randomString } from '../helper'; +import { downloadFile, validWallpaperPath, getWallpaperPath } from '../helper'; const platform = os.platform(); @@ -16,61 +14,21 @@ const platform = os.platform(); * @param image picture url */ export const setWallpaper = async (context: vscode.ExtensionContext, image: string): Promise => { - const configure = vscode.workspace.getConfiguration('artstation'); - const wallpaperPath = configure.get('wallpaperPath') as string; - const valid = validPath(wallpaperPath); + const valid = validWallpaperPath(); if (!valid) { return; } - const filePath = getWallpaperPath(image, wallpaperPath); + const filePath = getWallpaperPath(image); let saveFlag = false; try { - saveFlag = await saveWallpaper(image, filePath); - } catch { + saveFlag = await downloadFile(image, filePath); + } catch (err) { + console.error(err); vscode.window.showErrorMessage('Download wallpaper failed. 下载壁纸失败'); } saveFlag && setOSWallpaper(context, filePath); }; -const validPath = (str: string): boolean => { - if (!str) { - vscode.window.showErrorMessage([ - 'Please set wallpaper save path.', - '请先设置壁纸保存路径', - ].join(' ')); - return false; - } - if (!fs.lstatSync(str).isDirectory()) { - vscode.window.showErrorMessage([ - 'Wallpaper save path is incorrect', - '壁纸保存路径不正确', - ].join(' ')); - return false; - } - return true; -}; - -const getWallpaperPath = (imageUrl: string, wallpaperPath: string): string => { - const pathname = url.parse(imageUrl).pathname; - const basename = path.basename(pathname as string); - const filePath = path.join(wallpaperPath, `${randomString(5)}-${basename}`); - return filePath; -}; - -const saveWallpaper = (imageUrl: string, filePath: string): Promise => new Promise((resolve, reject) => { - const file = fs.createWriteStream(filePath); - https.get(imageUrl, (response) => { - response.pipe(file); - - file.on('finish', () => { - file.close(); - resolve(true); - }); - - file.on('error', err => reject(err)); - }).on('error', err => reject(err)); -}); - const setOSWallpaper = async (context: vscode.ExtensionContext, filePath: string) => { try { if (platform === 'darwin') { @@ -89,52 +47,31 @@ const setOSWallpaper = async (context: vscode.ExtensionContext, filePath: string } }; - export const downloadMacOSTool = async (context: vscode.ExtensionContext) => { if (platform !== 'darwin') { return; } const filePath = path.join(context.globalStorageUri.fsPath, 'macos-wallpaper'); - await downloadFile('https://github.com/IceEnd/Yosoro-Img/releases/download/0.0.1/macos-wallpaper', filePath); + try { + await downloadFile('https://github.com/IceEnd/Yosoro-Img/releases/download/0.0.1/macos-wallpaper', filePath); + showDownloadMessage(true); + } catch (error) { + showDownloadMessage(false, error); + } fs.chmodSync(filePath, 0o777); }; -export const downloadWindowsTool = (context: vscode.ExtensionContext) => { +export const downloadWindowsTool = async (context: vscode.ExtensionContext) => { if (platform !== 'win32') { return; } const filePath = path.join(context.globalStorageUri.fsPath, 'windows-wallpaper.exe'); - downloadFile('https://github.com/sindresorhus/win-wallpaper/releases/download/v1.1.2/wallpaper.exe', filePath); -}; - -const downloadFile = async (url: string, filePath: string): Promise => { - return new Promise(async (resolve, reject) => { - https.get(url, async (response) => { - if (response.statusCode === 302) { - try { - await downloadFile(response.headers.location as string, filePath); - resolve(true); - return; - } catch (error) { - reject(error); - } - } - const file = fs.createWriteStream(filePath); - response.pipe(file); - file.on('finish', () => { - file.close(); - showDownloadMessage(true); - resolve(true); - }); - file.on('error', err => { - reject(err); - showDownloadMessage(false, err); - }); - }).on('error', err => { - reject(err); - showDownloadMessage(false, err); - }); - }); + try { + await downloadFile('https://github.com/sindresorhus/win-wallpaper/releases/download/v1.1.2/wallpaper.exe', filePath); + showDownloadMessage(true); + } catch (error) { + showDownloadMessage(false, error); + } }; export const preDownload = (context: vscode.ExtensionContext) => { diff --git a/template/artstation.js b/template/artstation.js index 07cd2c5..1115039 100644 --- a/template/artstation.js +++ b/template/artstation.js @@ -37,6 +37,7 @@ bindFollow(); bindVotes(); bindSetBackground(); + bindDownload(); window.addEventListener('scroll', handleScroll); window.addEventListener('resize', handleResize); window.addEventListener('message', handleMessage); @@ -168,10 +169,22 @@ for: e.target.getAttribute('data-for'), }, }); - console.log(e.target); }); }; - /** DOM EVENTS: END **/ + + const bindDownload = () => { + const overlay = document.querySelector(SELECTORS.projectOverlay); + overlay.addEventListener('click', e => { + if (!e.target.classList.value.includes('asset-actions-btn-download')) { + return; + } + vscode.postMessage({ + command: 'download', + payload: e.target.getAttribute('data-url'), + }); + }); + }; + /** DOM EVENTS: END **/ const handleScroll = () => { if (state.loading) { diff --git a/template/styles/artstation.less b/template/styles/artstation.less index 1c2fa11..7a9c263 100644 --- a/template/styles/artstation.less +++ b/template/styles/artstation.less @@ -354,12 +354,13 @@ transform: translate(-50%, 0); z-index: 2; opacity: 0; + font-size: 0; transition: opacity .2s linear; box-shadow: 1px 1px 5px 0 rgb(0 0 0 / 50%); - &-btn-bg { + .btn { font-size: 12px; - padding: 6px 12px; + padding: 6px 8px; line-height: 1.8; border-radius: 2px; user-select: none; @@ -375,7 +376,7 @@ } } -@media screen and (min-width: 300px) { +@media screen and (min-width: 200px) { .gallery-grid { grid-template-columns: repeat(3, 1fr) !important; } @@ -385,6 +386,9 @@ .d-md-block { display: block !important; } + .gallery-grid { + grid-template-columns: repeat(3, 1fr) !important; + } } @media screen and (min-width: 640px) { diff --git a/template/styles/common.less b/template/styles/common.less index 38af9cc..17c6268 100644 --- a/template/styles/common.less +++ b/template/styles/common.less @@ -164,6 +164,10 @@ button { &.fa-cog:before { content: "\f013"; } + + &.fa-arrow-to-bottom:before { + content: "\f33d"; + } } .fa-pad-right {