Skip to content

Commit

Permalink
Merge pull request #142 from terwer/dev
Browse files Browse the repository at this point in the history
feat: 授权码模式的分享支持图片
  • Loading branch information
terwer committed Jul 2, 2023
2 parents a36b20b + 9b94c7f commit 5506914
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 75 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ Based on the localization concept of siyuan-note , this plugin is natively share

The core idea of this plugin is: `Everything is a Page` . You can set a page to be the home page.

> Important: Version 1.8.0+ unifies the sharing logic in public sharing and authorization code mode, so you need to initialize the sharing type to avoid the old sharing link access exception, you only need to open the sharing pop-up window once, and it will be automatically initialized after opening.
> Important:
> 1. Version 1.8.0+ unifies the sharing logic in public sharing and authorization code mode, so you need to initialize the sharing type to avoid the old sharing link access exception, you only need to open the sharing pop-up window once, and it will be automatically initialized after opening.
> 2. Sharing in 1.8.0+ authorization code mode can also support image display, go and try it 😄
[docs](https://blog.terwer.space/s/20230621001422-xsimx5v)

Expand All @@ -34,6 +36,8 @@ The core idea of this plugin is: `Everything is a Page` . You can set a page to
- [X] Support for custom domain names
- [X] Support for internal and external links
- [X] Support task list
- [X] Support enabling sharing under authorization code (experimental)
- [X] Unordered list style adaptation
- [ ] Bulk management of shared pages
- [ ] Support single page setting sharing password
- [ ] Integrate popular topics that are currently available
Expand All @@ -49,8 +53,6 @@ The core idea of this plugin is: `Everything is a Page` . You can set a page to
- [ ] plantuml chart support
- [ ] echats chart support
- [ ] Support svg with svOrigin, e.g. '<use xlink:href="#iconMore'>'</use>
- [X] Support enabling sharing under authorization code (experimental)
- [X] Unordered list style adaptation

## Changelog

Expand Down
10 changes: 6 additions & 4 deletions README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

本插件的核心理念是:`一切皆页面` 。您可以设置某个页面为主页。

> 重要提示:1.8.0+ 版本对公共分享和授权码模式下的分享逻辑进行了统一处理,因此需要初始化分享类型,避免旧的分享链接访问异常,您只需要打开一次分享弹窗即可,打开之后会自动初始化。
> 重要提示:
> 1. 1.8.0+ 版本对公共分享和授权码模式下的分享逻辑进行了统一处理,因此需要初始化分享类型,避免旧的分享链接访问异常,您只需要打开一次分享弹窗即可,打开之后会自动初始化。
> 2. 1.8.0+ 授权码模式下的分享也能支持图片显示啦,快去试试吧😄
[帮助文档](https://blog.terwer.space/s/20230621001422-xsimx5v)

Expand All @@ -26,14 +28,16 @@
- [入门级]思源笔记插件:零配置,开箱即用,本地SPA应用,直接访问思源本体,因此速度极快,但是SEO不太友好
- [高手级]docker自部署:需要自己购买服务器,SSR服务端渲染,SEO友好,速度快
- [白嫖级]Vercel托管:需要自己购买域名,否则可能无法访问,成本低,速度适中
- **分享模式(实验性)**:默认支持公共笔记分享,开启授权码之后可支持有限的分享功能。
- **分享模式**:默认支持公共笔记分享,开启授权码之后可支持有限的分享功能。

## TODO

- [X] 支持替换图片链接
- [X] 支持自定义域名
- [X] 支持内部链接和外部链接
- [X] 支持任务列表
- [X] 支持开启授权码下的分享
- [X] 无序列表样式适配
- [ ] 已分享页面的批量管理
- [ ] 支持单页面设置分享密码
- [ ] 集成目前已有的热门主题
Expand All @@ -49,8 +53,6 @@
- [ ] plantuml 图表支持
- [ ] echats 图表支持
- [ ] 支持思源自带的svg,例如 `<use xlink:href="#iconMore"></use>`
- [X] 支持开启授权码下的分享
- [X] 无序列表样式适配

## 更新历史

Expand Down
25 changes: 19 additions & 6 deletions components/default/Detail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,23 @@ const props = defineProps({
})
const { t } = useI18n()
const route = useRoute()
const { getFirstImageSrc } = useServerAssets()
const { currentPost, setCurrentPost } = usePost()
await setCurrentPost(props.pageId)
// datas
const formData = reactive({
shareEnabled: true,
isExpires: false,
})
const id = props.pageId ?? ((route.params.id ?? "") as string)
const attrs = JsonUtil.safeParse<any>(currentPost.post?.attrs ?? "{}", {})
const shareEnabled = attrs["custom-publish-status"] === "publish" || attrs["custom-publish-status"] === "preview"
const isExpires = checkExpires(attrs)
logger.info(`current document status,shareEnabled => ${shareEnabled}, isExpires => ${isExpires}`)
formData.shareEnabled = attrs["custom-publish-status"] === "publish" || attrs["custom-publish-status"] === "preview"
formData.isExpires = checkExpires(attrs)
logger.info(`current document status,shareEnabled => ${formData.shareEnabled}, isExpires => ${formData.isExpires}`)
if (!props.overrideSeo) {
const titleSign = " - " + t("blog.share")
const title = `${currentPost.post.title}${props.showTitleSign ? titleSign : ""}`
Expand Down Expand Up @@ -83,8 +91,9 @@ const VNode = () =>
</script>

<template>
<div v-if="!shareEnabled || isExpires">
<el-empty :description="isExpires ? t('blog.index.no.expires') : t('blog.index.no.permission')"> </el-empty>
<div v-if="!formData.shareEnabled || formData.isExpires">
<el-empty :description="formData.isExpires ? t('blog.index.no.expires') : t('blog.index.no.permission')">
</el-empty>
</div>
<div v-else class="fn__flex-1 protyle" data-loading="finished">
<div class="protyle-content protyle-content--transition" data-fullwidth="true">
Expand All @@ -100,12 +109,16 @@ const VNode = () =>
</div>
</div>
<div
v-highlight
v-beauty
v-domparser
class="protyle-wysiwyg protyle-wysiwyg--attr"
spellcheck="false"
contenteditable="false"
data-doc-type="NodeDocument"
:data-page-id="id"
>
<VNode v-highlight v-beauty v-domparser />
<VNode />
</div>
</div>
</div>
Expand Down
29 changes: 19 additions & 10 deletions components/static/Detail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { JsonUtil, ObjectUtil } from "zhi-common"
import { Post } from "zhi-blog-api"
import { createAppLogger } from "~/common/appLogger"
import { getSummery } from "~/utils/utils"
import { checkExpires, getSummery } from "~/utils/utils"
import { useServerAssets } from "~/plugins/renderer/useServerAssets"
import { useAuthModeFetch } from "~/composables/useAuthModeFetch"
Expand All @@ -52,20 +52,24 @@ const { getFirstImageSrc } = useServerAssets()
const { fetchPublicText } = useAuthModeFetch()
// datas
const formData = reactive({
post: {} as Post,
shareEnabled: true,
isExpires: false,
})
const getPostData = async () => {
const resText = await fetchPublicText(`${id}.json`)
formData.post = JsonUtil.safeParse<Post>(resText, {} as Post)
formData.shareEnabled = !ObjectUtil.isEmptyObject(formData.post)
// logger.info("post=>", formData.post)
// logger.info(`shareEnabled=>${formData.shareEnabled}`)
}
const formData = reactive({
post: {} as Post,
shareEnabled: true,
})
const attrs = JsonUtil.safeParse<any>(formData.post?.attrs ?? "{}", {})
formData.isExpires = checkExpires(attrs)
}
await getPostData()
if (!props.overrideSeo) {
const titleSign = " - " + t("blog.share")
const title = `${formData?.post?.title ?? "404 Not Found"}${props.showTitleSign ? titleSign : ""}`
Expand Down Expand Up @@ -94,8 +98,9 @@ const VNode = () =>
</script>

<template>
<div v-if="!formData.shareEnabled">
<el-empty :description="t('blog.index.no.permission')"> </el-empty>
<div v-if="!formData.shareEnabled || formData.isExpires">
<el-empty :description="formData.isExpires ? t('blog.index.no.expires') : t('blog.index.no.permission')">
</el-empty>
</div>
<div v-else class="fn__flex-1 protyle" data-loading="finished">
<div class="protyle-content protyle-content--transition" data-fullwidth="true">
Expand All @@ -111,12 +116,16 @@ const VNode = () =>
</div>
</div>
<div
v-highlight
v-sbeauty
v-sdomparser
class="protyle-wysiwyg protyle-wysiwyg--attr"
spellcheck="false"
contenteditable="false"
data-doc-type="NodeDocument"
:data-page-id="id"
>
<VNode v-highlight v-sbeauty v-sdomparser />
<VNode />
</div>
</div>
</div>
Expand Down
57 changes: 46 additions & 11 deletions composables/useStaticShare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,65 @@
import { useSiyuanApi } from "~/composables/api/useSiyuanApi"
import { createAppLogger } from "~/common/appLogger"
import { Post } from "zhi-blog-api"
import { useStaticClientAssets } from "~/plugins/renderer/useStaticClientAssets"

/**
* 静态分析相关处理(开启授权码模式)
*/
export const useStaticShare = () => {
const logger = createAppLogger("use-static-share")
const { kernelApi } = useSiyuanApi()
const { blogApi, kernelApi } = useSiyuanApi()
const { downloadAssetsToPublic } = useStaticClientAssets()

/**
* 打开静态分享
*
* @param {string} pageId - 页面ID
* @param {Post} post - 文章对象
*/
const openStaticShare = async (pageId: string, post: Post) => {
const updateSharePage = async (pageId: string, post: Post) => {
const shareJsonFile = `/data/public/siyuan-blog/${pageId}.json`
const pubicAssetsFolder = `/data/public/siyuan-blog/${pageId}`

// 保存图片附件
await downloadAssetsToPublic(post.editorDom, pubicAssetsFolder)
logger.info("assets downloaded success")

// 只暴露有限的属性
const sPost = new Post()
sPost.attrs = post.attrs
sPost.title = post.title
sPost.editorDom = post.editorDom
const sJson = JSON.stringify(sPost) ?? "{}"
await kernelApi.saveTextData(shareJsonFile, sJson)
logger.info("static share success")
}

const removeSharePage = async (pageId: string) => {
const shareJsonFile = `/data/public/siyuan-blog/${pageId}.json`
const pubicAssetsFolder = `/data/public/siyuan-blog/assets/${pageId}`

// 移除文档信息
await kernelApi.removeFile(shareJsonFile)

// 移除附件信息
await kernelApi.removeFile(pubicAssetsFolder)
logger.info("static share data removed success")
}
// ===========================================================================================

/**
* 打开静态分享
*
* @param {string} pageId - 页面ID
* @param {Post} post - 文章对象
*/
const openStaticShare = async (pageId: string, post: Post) => {
await updateSharePage(pageId, post)
}

/**
* 更新分享
*
* @param pageId - 文档ID
*/
const updateStaticShare = async (pageId: string) => {
const post = await blogApi.getPost(pageId, false, false)
await updateSharePage(pageId, post)
}

/**
Expand All @@ -57,9 +93,8 @@ export const useStaticShare = () => {
* @param {string} pageId - 页面ID
*/
const closeStaticShare = async (pageId: string) => {
const shareJsonFile = `/data/public/siyuan-blog/${pageId}.json`
await kernelApi.removeFile(shareJsonFile)
await removeSharePage(pageId)
}

return { openStaticShare, closeStaticShare }
return { openStaticShare, closeStaticShare, updateStaticShare }
}
13 changes: 1 addition & 12 deletions locales/en_US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,5 @@ export default {
"change.ip.title": "Change IP",
"share.accessCodeEnabled.tip":
"Special note: If you have enabled the authorization code after detection, please know if the document or settings are updated and need to be shared again.",
"share.accessCodeEnabled.tip0": "Special Notes:",
"share.accessCodeEnabled.tip1":
"1. If you have detected that you have enabled the authorization code, the sharing function is limited in this case, please make sure that you have understood the function limitations.",
"share.accessCodeEnabled.tip2": "The specific manifestations are:",
"share.accessCodeEnabled.tip3":
"(1) The document is shared statically, and it cannot be automatically updated after sharing, and you need to manually re-enable sharing if there is an update;",
"share.accessCodeEnabled.tip4": "(2) Sharing expiration is not supported, only sharing and unsharing are supported.",
"share.accessCodeEnabled.tip5": "(3) Does not support modifying the theme and does not support SEO.",
"share.accessCodeEnabled.tip6":
"2. If you need to experience the full function, you can cancel the authorization code and then share it.",
"share.accessCodeEnabled.tip7":
"3. If you really need to use the authorization code, you can ignore this prompt, but please make sure that you have fully understood the functional limitations in this mode.",
"share.public.tip": "Currently in public sharing mode",
}
9 changes: 1 addition & 8 deletions locales/zh_CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,5 @@ export default {
"form.nodata": "暂无数据",
"change.ip.title": "切换IP",
"share.accessCodeEnabled.tip": "特别提示:检测到您已开启授权码,若文档或者设置有更新,需重新分享,请知悉。",
"share.accessCodeEnabled.tip0": "特别提示:",
"share.accessCodeEnabled.tip1": "1、检测到您已开启授权码,此情况下分享功能受限,请确保已了解功能限制。",
"share.accessCodeEnabled.tip2": "具体表现为:",
"share.accessCodeEnabled.tip3": "(1)文档为静态分享,分享过后无法自动更新,有更新需要手动重新开启共享;",
"share.accessCodeEnabled.tip4": "(2)不支持分享过期,仅支持分享与取消分享。",
"share.accessCodeEnabled.tip5": "(3)不支持修改主题,不支持SEO。",
"share.accessCodeEnabled.tip6": "2、如需体验完整功能,可取消授权码后再分享。",
"share.accessCodeEnabled.tip7": "3、如果确实需要使用授权码,可忽略此提示,但请确保您已经完全了解此模式下的功能限制。",
"share.public.tip": "当前处于公共分享模式",
}
33 changes: 28 additions & 5 deletions pages/share.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const { getSetting, updateSetting } = useSettingStore()
const { blogApi, kernelApi } = useSiyuanApi()
const { getShareType, isPrivateShare } = useShareType()
const { updateShareType } = useCommonShareType()
const { openStaticShare, closeStaticShare } = useStaticShare()
const { openStaticShare, closeStaticShare, updateStaticShare } = useStaticShare()
const id = useRouteQuery("id", "")
const origin = useRouteQuery("origin", "")
Expand Down Expand Up @@ -183,6 +183,11 @@ const handleExpiresTime = async () => {
await kernelApi.setBlockAttrs(id.value, {
"custom-expires": expiredTime.toString(),
})
if (formData.accessCodeEnabled) {
await updateStaticShare(id.value)
logger.info("updated static share in auth mode")
}
},
() => {
if (isNaN(expiredTime) || expiredTime < 0 || expiredTime > 7 * 24 * 60 * 60) {
Expand All @@ -203,10 +208,6 @@ const handleIpChange = (val: string) => {

<template>
<div id="share">
<div v-if="formData.accessCodeEnabled" class="share-item">
<el-alert type="warning" :description="t('share.accessCodeEnabled.tip')"></el-alert>
</div>

<div class="share-item share-subject">
<div class="item-left">
{{ t("share.share") }}
Expand Down Expand Up @@ -327,6 +328,25 @@ const handleIpChange = (val: string) => {
</div>
-->
</div>
<el-divider class="share-split" />

<div class="share-item">
<div class="item-left">
<el-space direction="vertical">
<el-text>
<el-icon>
<el-icon-apple />
</el-icon>
<span v-if="formData.accessCodeEnabled" class="share-warn-tip">
{{ t("share.accessCodeEnabled.tip") }}
</span>
<span v-else>
{{ t("share.public.tip") }}
</span>
</el-text>
</el-space>
</div>
</div>
</div>
</template>

Expand Down Expand Up @@ -386,4 +406,7 @@ const handleIpChange = (val: string) => {
display inline-flex
.change-ip-title
margin-right 10px
.share-warn-tip
color: red;
padding-left: 6px;
</style>

1 comment on commit 5506914

@vercel
Copy link

@vercel vercel bot commented on 5506914 Jul 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.