<template>
	<view class="liu-editor">
			<!-- 工具栏 -->
			<view class="scroll">
				<view class="toolsBar-view">
					<view class="toolsBar-item" :class="{active:formats[item.name]}" @click="toolsBarItemClick(item)" v-for="(item,index) in toolbarList" :key="index">
						<image style="width: 30rpx;height: 30rpx;" :src="item.icon" mode=""></image>
					</view>
				</view>
			</view>
			
			<!-- 编辑器 -->
			<editor
				id="editor"
				:show-img-resize="true" 
				:show-img-size="true" 
				:show-img-toolbar="true" 
				:placeholder="placeholder" 
				@ready="onEditorReady"
				@statuschange="onStatusChange"
			></editor>
			
			<!-- 取色器 -->
			<!-- <t-color-picker ref="colorPicker" :color="color" @confirm="colorConfirm" @cancel="colorCancel"></t-color-picker> -->
		</view>
</template>

<script>
	export default {
			name: "liu-editor",
	
			props: {
				// 提示信息
				placeholder: {
					type: String,
					default: '开始输入...'
				},
				// 加载文字提示
				loadingText: {
					type: String,
					default: '上传中...'
				},
				// 上传图片时是否使用加载
				isLoading: {
					type: Boolean,
					default: true
				},
				// 图片上传路径
				uploadImgUrl: {
					type: String,
					default: ''
				},
				// 上传的配置参数
				uploadConfig:{
					type:Object,
					default:()=>({})
				},
				// 初始化文本信息
				html:{
					type:String,
					default:''
				}
			},
	
			data() {
				return {
					editorCtx: null, // 富文本上下文api
					formats:{}, // 点前选择的样式集
					
					// 工具栏
					toolbarList:[
						{
							name:'image', // 图片上传
							icon:'/static/editor-img/image.png',
							type:'upload', // 上传类型
						},
						{
							name:'previewFun', // 预览
							icon:'/static/editor-img/preview.png',
							type:'click', // 点击类型
						},
						{
							name:'header', // 文字标题(header)
							icon:'/static/editor-img/header.png',
							type:'select', // 选择类型
							value:[
								{
									name:'一级标题',
									value:'H1'
								},
								{
									name:'二级标题',
									value:'H2'
								},
								{
									name:'三级标题',
									value:'H3'
								},
								{
									name:'四级标题',
									value:'H4'
								},
								{
									name:'五级标题',
									value:'H5'
								},
								{
									name:'六级标题',
									value:'H6'
								}
							]
						},
						{
							name:'bold', // 文字加粗(bold)
							icon:'/static/editor-img/bold.png',
							type:'click', // 点击类型
						},
						{
							name:'italic', // 文字斜体(italic)
							icon:'/static/editor-img/italic.png',
							type:'click', // 点击类型
						},
						{
							name:'underline', // 文字下划线(underline)
							icon:'/static/editor-img/underline.png',
							type:'click', // 点击类型
						},
						{
							name:'strike', // 文字删除线(strike)
							icon:'/static/editor-img/strike.png',
							type:'click', // 点击类型
						},
						{
							name:'indent', // 文字缩进(indent)
							icon:'/static/editor-img/indent.png',
							type:'select', // 选择类型
							value:[
								{
									name:'向右缩进',
									value:'+1',
								},
								{
									name:'向左缩进',
									value:'-1'
								}
							]
						},
						{
							name:'list', // 列表(list)
							icon:'/static/editor-img/list.png',
							type:'select', // 选择类型
							value:[
								{
									name:'有序列表',
									value:'ordered',
								},
								{
									name:'无序列表',
									value:'bullet'
								},
								{
									name:'方框列表',
									value:'check'
								}
							], // 数字 、点、方框
						},
						{
							name:'lineHeight', // 文字行高(lineHeight)
							icon:'/static/editor-img/lineHeight.png',
							type:'select', // 选择类型
							value:[
								{
									name:'1',
									value:'1'
								},
								{
									name:'1.5',
									value:'1.5'
								},
								{
									name:'2',
									value:'2'
								},
								{
									name:'2.5',
									value:'2.5'
								},
								{
									name:'3',
									value:'3'
								}
							],
						},
						{
							name:'fontSize', // 文字大小(fontSize)
							icon:'/static/editor-img/fontSize.png',
							type:'select', // 选择类型
							value:[
								{
									name:'10px',
									value:'10px'
								},
								{
									name:'13px',
									value:'13px'
								},
								{
									name:'16px',
									value:'16px'
								},
								{
									name:'18px',
									value:'18px'
								},
								{
									name:'24px',
									value:'24px'
								},
								{
									name:'32px',
									value:'32px'
								},
								{
									name:'48px',
									value:'48px'
								}
							],
						},
						{
							name:'align', // 文字排版(align)
							icon:'/static/editor-img/align.png',
							type:'select', // 选择类型
							value:[
								{
									name:'左对齐',
									value:'left'
								},
								{
									name:'居中对齐',
									value:'center'
								},
								{
									name:'右对齐',
									value:'right'
								},
								{
									name:'整行对齐',
									value:'justify'
								}
							],
						},
						{
							name:'color', // 文字颜色(color)
							icon:'/static/editor-img/color.png',
							type:'popup', // 弹窗类型
						},
						{
							name:'undoFun', // 撤销
							icon:'/static/editor-img/undo.png',
							type:'click', // 点击类型
						},
						{
							name:'redoFun', // 恢复
							icon:'/static/editor-img/redo.png',
							type:'click', // 点击类型
						},
						{
							name:'margin', // 外边距(margin)
							icon:'/static/editor-img/margin.png',
							type:'select', // 选择类型
							value:[
								{
									name:'四周外边距',
									value:'margin',
								},
								{
									name:'上外边距',
									value:'marginTop',
								},
								{
									name:'下外边距',
									value:'marginBottom',
								},
								{
									name:'左外边距',
									value:'marginLeft',
								},
								{
									name:'右外边距',
									value:'marginRight',
								}
							],
						},
						{
							name:'padding', // 内边距(padding)
							icon:'/static/editor-img/padding.png',
							type:'select', // 选择类型
							value:[
								{
									name:'四周内边距',
									value:'padding',
								},
								{
									name:'上内边距',
									value:'paddingTop',
								},
								{
									name:'下内边距',
									value:'paddingBottom',
								},
								{
									name:'左内边距',
									value:'paddingLeft',
								},
								{
									name:'右内边距',
									value:'paddingRight',
								}
							],
						},
						{
							name:'clearFun', // 清空编辑器内容
							icon:'/static/editor-img/clear.png',
							type:'click', // 选择类型
						}
						
					],
					
					// color
					color: {
						r: 255,
						g: 0,
						b: 0,
						a: 0.6
					},
					
				};
			},
			
			watch:{
				html(n,o){
					n && this.onEditorReady();
				}
			},
	
			methods: {
				
				// 取色器确定事件
				colorConfirm(e) {
					// console.log(e);
					this.format('color',e.hex);
				},
				// 取色器取消事件
				colorCancel() {
					// console.log('取消');
				},
				
				// 初始化
				onEditorReady() {
					if( this.editorCtx ){
						this.html && this.initEditor()
						return;
					}
					uni.createSelectorQuery().select('#editor').context((res) => {
						if( res.context ){
							this.editorCtx = res.context;
							this.html && this.initEditor()
						}
					}).exec()
				},
				
				// 设置样式时触发
				onStatusChange(e){
					this.formats = e.detail;
				},
				
				// 设置样式
				format(name,value){
					this.editorCtx.format(name,value);
				},
	
				// 插入图片
				insertImage() {
	
					uni.chooseImage({
						success: async (res) => {
							// console.log(res);
							// res.tempFilePaths
							if (res.tempFilePaths.length) {
								// console.log(res.tempFilePaths);
								// 加载
								this.isLoading && uni.showLoading({title: this.loadingText,mask:true});
								
								for (let i = 0,ilen=res.tempFilePaths.length; i < ilen; i++) {
									try{
										let [err,img_res] = await this.uploadImageSync(res.tempFilePaths[i]);
										let resData = JSON.parse(img_res.data);
										// console.log(resData);
										if( !resData.error_code ){
											uni.hideLoading();
											this.editorCtx.insertImage({
												src:resData.data.uri,
												alt:'图片',
												extClass:'editor--editor-img'
												// width:'100%',
											})
											this.editorCtx.insertText({text:' '});
											
										}else{
											uni.hideLoading();
											this.toast('图片上传失败');
										}
									}catch(e){
										//TODO handle the exception
										uni.hideLoading();
										this.toast('上传图片发生错误');
									}
									
								}
								// console.log(1122);
							}
						},
						fail: (err) => {
							console.log(err);
						}
					})
				},
				
				// 初始化文本信息
				initEditor(){
					this.editorCtx.setContents({html:this.html});
				},
	
				// 图片上传
				uploadImageSync(filePath) {
					// 没有上传路径 直接返回 filePath
					if( !this.uploadImgUrl ){return filePath};
					let header = this.uploadConfig.header || {};
					let formData = this.uploadConfig.formData || {};
					// 返回 promise对象
					return uni.uploadFile({
						url: this.uploadImgUrl,
						filePath,
						header:{
							// #ifdef APP-PLUS
							'content-type': 'multipart/form-data',
							// #endif
							...header
						},
						// #ifdef APP-PLUS
						name: 'file',
						// #endif
						formData,
					});
				},
				
				// 轻提示
				toast(title,duration=1000,icon='none'){
					uni.showToast({title,duration,icon});
				},
				
				// 工具栏点击事件
				toolsBarItemClick(item){
					let switchFun = {
						// 点击类型
						'click':()=>{
							let keys = {previewFun:1,undoFun:1,redoFun:1,clearFun:1};
							if(  keys[item.name] ){
								return this[item.name] && this[item.name]();
							}
							this.format(item.name,item.value);
						},
						// 弹窗类型
						'popup':()=>{
							if( this.formats[item.name] ){
								return this.format(item.name,'');
							}
							this.$refs.colorPicker.open();
						},
						// 选择类型
						'select':()=>{
							if( this.formats[item.name] ){
								return this.format(item.name,'');
							}
							let keys = item.value.map(item=>item.name);
							if( item.name === 'margin' || item.name === 'padding' ){
								uni.showActionSheet({
								    itemList: keys,
								    success: resOne=>{
										let name = item.value[resOne.tapIndex].value;
										setTimeout(()=>{
											let list = ['0px','10px','15px','20px','25px','30px'];
											uni.showActionSheet({
											    itemList: list,
											    success: resTwo=>{
													this.format(name,list[resTwo.tapIndex]);
													// console.log(name,list[resTwo.tapIndex]);
											    }
											});
										},100);
										
								    },
								    fail: function (res) {
								        console.log(res.errMsg);
								    }
								});
								return;
							}
							uni.showActionSheet({
							    itemList: keys,
							    success: res=>{
									this.format(item.name,item.value[res.tapIndex].value);
							    },
							    fail: function (res) {
							        console.log(res.errMsg);
							    }
							});
						},
						// 上传类型
						'upload':()=>{
							this.insertImage();
						}
					}
					switchFun[item.type] && switchFun[item.type]();
				},
				
				// 预览
				async previewFun(){
					// this.toast('预览');
					let res = await this.editorGetContents();
					if( res.html ){
						uni.setStorageSync('editorPreviewHtml',res.html);
					}
					uni.navigateTo({url:'/pages/editorPreview/editorPreview'});
				},
				// 撤销
				undoFun(){
					this.toast('撤销');
					this.editorCtx.undo();
				},
				// 清空编辑器内容
				clearFun(){
					uni.showModal({
						content:'确定清空编辑器内容？',
						success: res => {
							if( res.confirm ){
								this.editorCtx.clear();
							}
						}
					})
				},
				
				// 获取编辑器内容
				editorGetContents(cb){
					return new Promise((resolve,reject)=>{
						this.editorCtx.getContents({
							success:res=>{
								resolve(res);
							},
							fail:err=>{
								reject(err);
							}
						})
					});
				},
				
				
			}
		}
</script>

<style>
	.liu-editor {
			width: 100%;
			background-color: #fff;
		}
		
		.toolsBar-view{
			display: flex;
			align-items:center;
			background-color: #F2F2F2;
			padding-left: 20rpx;
			border-bottom: 4rpx solid #e1e1e1;
		}
		.toolsBar-item{
			margin-right:25rpx;
			width: 50rpx;
			height: 50rpx;
			background-color: #fff;
			display: flex;
			align-items: center;
			justify-content: center;
		}
		.toolsBar-item.active{
			background-color: rgba(255,85,0,0.5);
		}
	
		.scroll{
			width: 100%;
			height: 80rpx;
			overflow: hidden;
			overflow-x: auto;
			display: flex;
		}
		
		#editor {
			padding: 20rpx 20rpx 20rpx;
			background-color: #F2F2F2;
			box-sizing: border-box;
			width: 100%;
			height: 100%;
			font-size: 16px;
			line-height: 1.5;
			overflow: auto;
		}
</style>