diff --git a/oauthInfo.json b/oauthInfo.json
index 5cf504e..8c2580f 100644
--- a/oauthInfo.json
+++ b/oauthInfo.json
@@ -13,12 +13,5 @@
"authorizationUrl": "https://www.tistory.com/oauth/authorize",
"tokenUrl": "https://www.tistory.com/oauth/access_token",
"redirectUri": "http://localhost"
- },
- "google": {
- "clientId": "CLIENT_ID",
- "clientSecret": "CLIENT_SECRET",
- "authorizationUrl": "https://accounts.google.com/o/oauth2/auth",
- "tokenUrl": "https://accounts.google.com/o/oauth2/token",
- "redirectUri": "http://localhost"
- }
+ }
}
diff --git a/src/main/apis/photos-api.js b/src/main/apis/photos-api.js
deleted file mode 100644
index d6a1655..0000000
--- a/src/main/apis/photos-api.js
+++ /dev/null
@@ -1,120 +0,0 @@
-const oauth2 = require('../oauth/ElectronOauth2');
-const ExternalOAuth2 = require('../oauth/ExternalOAuth2')
-const fetch = require('isomorphic-fetch')
-const {clipboard, session} = require('electron')
-const OauthInfoReader = require('../oauth/OauthInfoReader')
-const appInfo = require('../appInfo');
-const OAuthRequestManager = require('../oauth/OAuthRequestManager');
-
-class GoogleAuthApi {
- #googleOAuth
-
- constructor() {
- this.#googleOAuth = null
- }
-
- makeGoogleOAuth() {
- if (!this.#googleOAuth) {
- const oauthInfoReader = new OauthInfoReader()
- const oauthInfo = oauthInfoReader.getGoogle()
-
- this.#googleOAuth = oauth2(oauthInfo, {
- alwaysOnTop: true,
- autoHideMenuBar: true,
- webPreferences: {
- nodeIntegration: false,
- contextIsolation: true,
- session: session.fromPartition("google:oauth2:" + new Date())
- }
- })
- }
-
- return this.#googleOAuth
- }
-
- requestAuth(successHandler, failureHandler) {
- const oauthInfoReader = new OauthInfoReader()
- const oauth2 = new ExternalOAuth2(oauthInfoReader.getGoogle())
- OAuthRequestManager.saveRequestInfo("oauth", (searchParams) => {
- const code = searchParams.get("code")
- oauth2.requestToken(code)
- .then(data => {
- if (data.error) {
- throw new Error(`${data.error}: ${data.error_description}`)
- }
-
- return data
- })
- .then(successHandler)
- .catch(failureHandler)
- })
-
- oauth2.requestAuth({
- scope: ['https://www.googleapis.com/auth/photoslibrary.readonly']
- })
- }
-
- getAccessToken() {
- return this.makeGoogleOAuth().getAccessToken({
- scope: ['https://www.googleapis.com/auth/photoslibrary.readonly']
- })
- }
-
- refreshToken(refreshToken) {
- return this.makeGoogleOAuth().refreshToken(refreshToken)
- }
-}
-module.exports.GoogleAuthApi = GoogleAuthApi
-
-
-class PhotosApi {
- constructor(auth) {
- this.auth = auth
- }
-
- fetchMediaItems(pageSize = 100, nextPageToken = null) {
- console.log("fetchMediaItems", this.auth.access_token, pageSize, nextPageToken)
- return fetch('https://photoslibrary.googleapis.com/v1/mediaItems:search', {
- method: 'post',
- headers: {
- 'Content-type': 'application/json',
- 'Authorization': `Bearer ${this.auth.access_token}`
- },
- body: JSON.stringify({
- pageSize: pageSize,
- pageToken: nextPageToken,
- filters: {
- mediaTypeFilter: {
- mediaTypes: ['PHOTO']
- }
- }
- })
- })
- .then(res => {
- if (!res.ok) {
- console.error("fetch failed", res)
- throw new Error(res.status)
- }
-
- return res.json()
- })
- .then(json => {
- return {
- images: json.mediaItems.map(item => {
- const width = item.mediaMetadata.width > 1920? 1920 : item.mediaMetadata.width
- const thumbnailWidth = 340
- return {
- id: item.id,
- url: `${item.baseUrl}=w${width}`,
- thumbnail: `${item.baseUrl}=w${thumbnailWidth}`,
- title: item.filename,
- timestamp: item.mediaMetadata.creationTime
- }
- }),
- nextPageToken: json.nextPageToken
- }
-
- })
- }
-}
-module.exports.PhotosApi = PhotosApi
diff --git a/src/main/events/google-photos.js b/src/main/events/google-photos.js
deleted file mode 100644
index b98cb1e..0000000
--- a/src/main/events/google-photos.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const { ipcMain } = require('electron')
-const settings = require('electron-settings')
-const { GoogleAuthApi, PhotosApi } = require('../apis/photos-api')
-
-module.exports = () => {
- const authApi = new GoogleAuthApi()
- const fetchImages = async (evt, nextPageToken) => {
- console.log('fetchImage', nextPageToken)
- const auth = settings.getSync('google-auth')
-
- try {
- if (!auth || !auth.access_token) {
- throw new Error("NO_AUTH")
- }
- evt.sender.send('start-fetch-google-photos-images')
- const photosApi = new PhotosApi(auth)
- const data = await photosApi.fetchMediaItems(100, nextPageToken)
- evt.sender.send('receive-google-photos-images', data)
-
- } catch(e) {
- console.error(e)
- if (auth && auth.refresh_token) {
- try {
- const refreshAuth = await authApi.refreshToken(auth.refresh_token)
- settings.setSync('google-auth', refreshAuth)
- fetchImages(evt, nextPageToken)
- return
- } catch (authError) {
- settings.setSync('google-auth', null)
- evt.sender.send('receive-google-connected', false)
- }
- } else {
- evt.sender.send('receive-google-connected', false)
- }
- evt.sender.send('receive-google-photos-images', null)
- }
- }
-
- ipcMain.on('fetch-google-photos-images', (evt, nextPageToken) => {
- console.log('Main.receive: fetch-google-photos-images', nextPageToken)
- fetchImages(evt, nextPageToken)
- })
-
- ipcMain.on("request-google-photos-auth", (evt, arg) => {
- console.log('Main.receive: request-google-photos-auth')
- authApi.requestAuth((auth) => {
- settings.setSync('google-auth', auth)
- evt.sender.send('receive-google-connected', true)
- fetchImages(evt, null)//
- }, (e) => {
- console.error(e)
- evt.sender.send('receive-message', `오류가 발생했습니다. (${e.message})`)
- })
- })
-
- ipcMain.on("disconnect-google-photos-auth", (evt, arg) => {
- console.log('Main.receive: disconnect-google-photos-auth')
- settings.unsetSync('google-auth')
- evt.sender.send('receive-google-connected', false)
- })
-}
diff --git a/src/main/ipc-event.js b/src/main/ipc-event.js
index aa7fccc..afb3f10 100644
--- a/src/main/ipc-event.js
+++ b/src/main/ipc-event.js
@@ -1,13 +1,11 @@
const authEvents = require('./events/auth')
const contentEvents = require('./events/content')
const preferenceEvents = require('./events/preference')
-const googlePhotosEvents = require('./events/google-photos')
const googleAnalyticsEvents = require('./events/google-analytics')
module.exports.init = () => {
authEvents()
contentEvents()
preferenceEvents()
- googlePhotosEvents()
googleAnalyticsEvents()
}
diff --git a/src/renderer/components/editor/codemirror/MarkdownEditor.js b/src/renderer/components/editor/codemirror/MarkdownEditor.js
index 7f0d6e4..309edbe 100644
--- a/src/renderer/components/editor/codemirror/MarkdownEditor.js
+++ b/src/renderer/components/editor/codemirror/MarkdownEditor.js
@@ -8,8 +8,6 @@ import { Button, Box } from '@mui/material'
import { FormatBold, FormatItalic, FormatUnderlined, Attachment } from '@mui/icons-material'
import CodeMirrorHelper from './CodeMirrorHelper'
-import GooglePhotosDialog from '../plugins/google-photos/GooglePhotosDialog'
-import googlePhotosLogo from '../../../images/google-photos-logo.png'
import "../../../styles/lib/codemirror/tistory-markdown-theme.scss"
import "codemirror/lib/codemirror.css"
import "codemirror/addon/dialog/dialog.css"
@@ -75,7 +73,6 @@ export default function MarkdownEditor({ value, onOpenFile, onChange }) {
const currentAuth = useSelector(state => state.currentAuth)
const currentBlog = useSelector(state => state.currentBlog)
const [markdownValue, setMarkdownValue] = useState(MarkdownHelper.htmlToMarkdown(value))
- const [openGooglePhotos, setOpenGooglePhotos] = useState(false)
const editorRef = useRef(null)
const imageUploadEnabled = useMemo(() => currentAuth.provider == 'tistory', [currentAuth])
@@ -124,18 +121,6 @@ export default function MarkdownEditor({ value, onOpenFile, onChange }) {
CodeMirrorHelper.link(editorRef.current.getCodeMirror())
}
- function handleGooglePhotos(e) {
- setOpenGooglePhotos(true)
- }
-
- function handleCloseGooglePhotos() {
- setOpenGooglePhotos(false)
- }
-
- function handleInsertImage(url, fileName) {
- ipcRenderer.send("add-image-url", currentAuth.uuid, currentBlog.name, url, fileName)
- }
-
function handleFinishUploadFile(e, fileUrl) {
CodeMirrorHelper.insertImage(editorRef.current.getCodeMirror(), fileUrl)
}
@@ -163,7 +148,6 @@ export default function MarkdownEditor({ value, onOpenFile, onChange }) {
Link
- {imageUploadEnabled && }
{imageUploadEnabled && }
@@ -178,12 +162,6 @@ export default function MarkdownEditor({ value, onOpenFile, onChange }) {
value={markdownValue}
onChange={handleChangeContent}
/>
-
-
)
}
diff --git a/src/renderer/components/editor/plugins/google-photos/GooglePhotos.js b/src/renderer/components/editor/plugins/google-photos/GooglePhotos.js
deleted file mode 100644
index 85362b6..0000000
--- a/src/renderer/components/editor/plugins/google-photos/GooglePhotos.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import React, { useEffect, useState } from 'react'
-import { ipcRenderer } from 'electron'
-import update from 'immutability-helper'
-import { Button } from '@mui/material'
-import Loading from '../../../Loading'
-import PhotoList from './PhotoList'
-
-
-export default function GooglePhotos({ connected, onConnect, onDisconnect, onSelectImage }) {
- const [initialized, setInitialized] = useState(false)
- const [images, setImages] = useState([])
- const [fetching, setFetching] = useState(false)
- const [nextPageToken, setNextPageToken] = useState(null)
-
- function handleReceiveImages(e, data) {
- if (data === null) {
- onDisconnect()
- return
- }
-
- console.log("connected", data)
-
- setInitialized(true)
- setImages(update(images, {
- $push: data.images
- }))
- setNextPageToken(data.nextPageToken)
- setFetching(false)
- onConnect(true)
- }
-
- function handleStartFetch(e) {
- setFetching(true)
- }
-
- function handleReceiveConnected(e, connected) {
- setInitialized(true)
-
- if (connected) {
- onConnect()
- } else {
- setImages([])
- setNextPageToken(null)
- onDisconnect()
- }
- }
-
- function handleRequestFetch() {
- ipcRenderer.send('fetch-google-photos-images', nextPageToken)
- }
-
- function handleRequestAuth() {
- ipcRenderer.send("request-google-photos-auth")
- }
-
- function handleImageSelect(image) {
- if (confirm('이미지를 삽입하시겠습니까?')) {
- onSelectImage(image.url, image.title)
- }
- }
-
- useEffect(() => {
- handleRequestFetch()
- ipcRenderer.on("receive-google-photos-images", handleReceiveImages)
- ipcRenderer.on("start-fetch-google-photos-images", handleStartFetch)
- ipcRenderer.on("receive-google-connected", handleReceiveConnected)
-
- return () => {
- ipcRenderer.removeListener("receive-google-photos-images", handleReceiveImages)
- ipcRenderer.removeListener("start-fetch-google-photos-images", handleStartFetch)
- ipcRenderer.removeListener("receive-google-connected", handleReceiveConnected)
- }
- }, [])
-
-
- if (!initialized) {
- return (
-
- )
- }
-
- if (!connected) {
- return (
-
-
-
-
-
- )
- }
-
- return (
-
- )
-}
diff --git a/src/renderer/components/editor/plugins/google-photos/GooglePhotosDialog.js b/src/renderer/components/editor/plugins/google-photos/GooglePhotosDialog.js
deleted file mode 100644
index d9acc96..0000000
--- a/src/renderer/components/editor/plugins/google-photos/GooglePhotosDialog.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import React, { Component } from 'react'
-import autobind from 'autobind-decorator'
-import { ipcRenderer } from 'electron'
-
-import { Dialog, Button, DialogTitle, DialogContent, DialogActions } from '@mui/material'
-import GooglePhotos from './GooglePhotos'
-
-class GooglePhotosDialog extends Component {
-
- constructor(props) {
- super(props)
- this.state = {
- connected: false
- }
- }
-
- @autobind
- handleDisconnect() {
- this.setState({
- connected: false
- })
- }
-
- @autobind
- handleConnect() {
- this.setState({
- connected: true
- })
- }
-
- @autobind
- handleRequestDisconnect() {
- ipcRenderer.send("disconnect-google-photos-auth")
- }
-
- render() {
- const { connected } = this.state
- const { open, onClose, onSelectImage } = this.props
-
- return(
-
- )
- }
-}
-
-export default GooglePhotosDialog
diff --git a/src/renderer/components/editor/plugins/google-photos/PhotoList.js b/src/renderer/components/editor/plugins/google-photos/PhotoList.js
deleted file mode 100644
index 7105689..0000000
--- a/src/renderer/components/editor/plugins/google-photos/PhotoList.js
+++ /dev/null
@@ -1,110 +0,0 @@
-import React, { Component, Fragment } from 'react'
-import autobind from 'autobind-decorator'
-
-import {
- ImageList, ImageListItem, ImageListItemBar,
- ListSubheader,
- IconButton
-} from '@mui/material'
-
-import { AddCircleOutline } from '@mui/icons-material'
-
-import Loading from '../../../../components/Loading'
-import { timestampsToDate } from '../../../../modules/ContentHelper'
-
-const styles = {
- buttonIcon: {
- color: 'rgba(255, 255, 255, 0.54)'
- },
- gridTitleBar: {
- background: 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)'
- }
-}
-
-class PhotoList extends Component {
-
- componentDidMount() {
- const { album, onBack } = this.props
- const { list } = this.refs
- list.addEventListener('scroll', this.handleScrollList)
- }
-
- componentWillUnmount() {
- const { list } = this.refs
- list.removeEventListener('scroll', this.handleScrollList)
- }
-
- @autobind
- handleScrollList(e) {
- const { onFetch, images, fetching } = this.props
- const { clientHeight, scrollHeight, scrollTop } = e.target
-
- if (fetching) {
- return
- }
-
- if (clientHeight + scrollTop + 200 > scrollHeight) {
- onFetch()
- }
- }
-
- render() {
- const { onClick, images, fetching } = this.props
-
- let lastDate = ''
- let currentDate = ''
-
- return (
-
-
- {images.length === 0 && fetching &&
-
-
-
- }
-
- {images.length > 0 &&
-
- {images.map(item => {
- let prevDate = currentDate
- currentDate = timestampsToDate(item.timestamp)
-
- let tile = [
-
-
- onClick(item)}>
-
-
- }
- />
-
- ]
-
- if (prevDate != currentDate) {
- tile.unshift(
-
- {currentDate}
-
- )
- }
-
- return tile
- })}
-
- }
-
- {images.length > 0 && fetching &&
-
-
-
- }
-
-
- )
- }
-}
-
-export default PhotoList
diff --git a/src/renderer/components/editor/tinymce/TinymceEditor.js b/src/renderer/components/editor/tinymce/TinymceEditor.js
index d183150..c6d3b9b 100644
--- a/src/renderer/components/editor/tinymce/TinymceEditor.js
+++ b/src/renderer/components/editor/tinymce/TinymceEditor.js
@@ -8,7 +8,6 @@ import { Editor } from '@tinymce/tinymce-react'
import 'tinymce-plugin-opengraph'
import 'tinymce-plugin-codeblock'
-import './plugins/google-photos'
import './plugins/file-upload'
import 'codemirror/mode/clojure/clojure'
@@ -17,25 +16,24 @@ import 'codemirror/mode/clike/clike'
import 'codemirror/mode/go/go'
import 'codemirror/mode/xml/xml'
-import GooglePhotosDialog from '../plugins/google-photos/GooglePhotosDialog'
import { makeThumbnail } from '../../../modules/ThumbnailHelper'
export default function TinymceEditor({ value, onImageHandler, onOpenFile, onChange }) {
const currentAuth = useSelector(state => state.currentAuth)
const currentBlog = useSelector(state => state.currentBlog)
- const [openGooglePhotos, setOpenGooglePhotos] = useState(false)
const imageUploadEnabled = useMemo(() => currentAuth.provider == 'tistory', [currentAuth])
const tinymcePlugins = useMemo(() => {
if (imageUploadEnabled) {
- return 'link table lists codeblock opengraph google-photos file-upload autoresize searchreplace'
+ return 'link table lists codeblock opengraph file-upload autoresize searchreplace'
} else {
return 'link table lists codeblock opengraph autoresize searchreplace'
}
}, [imageUploadEnabled])
+
const tinymceToolbar = useMemo(() => {
if (imageUploadEnabled) {
- return 'blocks bold italic link inlinecode | alignleft aligncenter alignright | bullist numlist | blockquote codeblock google-photos file-upload opengraph hr removeformat'
+ return 'blocks bold italic link inlinecode | alignleft aligncenter alignright | bullist numlist | blockquote codeblock file-upload opengraph hr removeformat'
} else {
return 'blocks bold italic link inlinecode | alignleft aligncenter alignright | bullist numlist | blockquote codeblock opengraph hr removeformat'
}
@@ -86,17 +84,6 @@ export default function TinymceEditor({ value, onImageHandler, onOpenFile, onCha
})
}
- function handleInsertImage(url, filename) {
- if (!imageUploadEnabled) {
- return
- }
- ipcRenderer.send("add-image-url", currentAuth.uuid, currentBlog.name, url, filename)
- }
-
- function handleToggleGooglePhotos() {
- setOpenGooglePhotos(!openGooglePhotos)
- }
-
useEffect(() => {
ipcRenderer.on("finish-add-file", handleFinishUploadFile)
@@ -145,9 +132,6 @@ export default function TinymceEditor({ value, onImageHandler, onOpenFile, onCha
opengraph: {
fetch_handler: handleFetchOpengraph
},
- google_photos: {
- open_handler: handleToggleGooglePhotos
- },
open_file_handler: onOpenFile,
init_instance_callback: (editor) => {
editor.ui.registry.addIcon('media', 'M')
@@ -156,12 +140,6 @@ export default function TinymceEditor({ value, onImageHandler, onOpenFile, onCha
}
}}
/>
-
-
>
)
}
diff --git a/src/renderer/components/editor/tinymce/plugins/google-photos/index.js b/src/renderer/components/editor/tinymce/plugins/google-photos/index.js
deleted file mode 100644
index 12fdf4b..0000000
--- a/src/renderer/components/editor/tinymce/plugins/google-photos/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import tinymce from 'tinymce'
-import plugin from './plugin'
-
-tinymce.PluginManager.add('google-photos', plugin)
diff --git a/src/renderer/components/editor/tinymce/plugins/google-photos/plugin.js b/src/renderer/components/editor/tinymce/plugins/google-photos/plugin.js
deleted file mode 100644
index efd1261..0000000
--- a/src/renderer/components/editor/tinymce/plugins/google-photos/plugin.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import googlePhotosLogo from '../../../../../images/google-photos-logo.png'
-
-const plugin = function(editor) {
- editor.options.register("google_photos", {
- processor: 'object'
- })
-
- const settings = editor.options.get("google_photos")
- if (!settings.open_handler) {
- return
- }
-
-
-
- editor.addCommand('google-photos', settings.open_handler)
- editor.ui.registry.addIcon('google-photos', ``)
-
- editor.ui.registry.addButton('google-photos', {
- icon: 'google-photos',
- tooltip: 'Google Photos',
- onAction: () => {
- editor.execCommand('google-photos')
- }
- })
-}
-
-export default plugin
diff --git a/src/renderer/images/google-photos-logo.png b/src/renderer/images/google-photos-logo.png
deleted file mode 100644
index a368568..0000000
Binary files a/src/renderer/images/google-photos-logo.png and /dev/null differ
diff --git a/src/renderer/styles/components/rich-editor.scss b/src/renderer/styles/components/rich-editor.scss
index 4a92301..3a28d9e 100644
--- a/src/renderer/styles/components/rich-editor.scss
+++ b/src/renderer/styles/components/rich-editor.scss
@@ -28,60 +28,3 @@
}
}
}
-
-/* photos plugin */
-.ico-google-photos {
- display:inline-block; width: 16px; height:16px;
- background:url('../images/google-photos-logo.png') no-repeat; background-size:16px 16px;
-}
-.tox-container .plugin-google-photos { min-width:640px }
-
-.btn-disconnect-google-photos {
- position: absolute !important; left:0;
-}
-.plugin-google-photos {
- min-width: 640px; min-height:480px; position: relative;
- .google-photos-wrap {
- position:absolute; top:0; bottom:0; left:0; right:0; overflow:auto;
- .google-photos-cover { display: flex;justify-content: center;align-items: center; height: 100%;}
- .google-photos-footer { display: flex;justify-content: center;align-items: center; height: 100px; width:100%; }
-
- .photos-list {
- position:absolute; top:0; bottom:0; left:0; right:0; overflow:hidden; overflow-y:auto;
-
-
- .photos-item-wrap {
- margin: -2px;
-
- .photos-sub-header {
- clear: both;
- padding: 20px;
- }
-
- .photos-item {
- float: left;
- width: 50%;
- height: 184px;
- box-sizing: border-box;
- flex-shrink: 0;
-
- .photos-item-image-wrap {
- height: 100%;
- display:block;
- position: relative;
- overflow: hidden;
-
- .photos-item-image {
- left: 50%;
- top: 50%;
- width: 100%;
- position: relative;
- transform: translate(-50%, -50%);
- }
- }
- }
- }
- }
- }
-
-}