├── plugins ├── xhr │ ├── index.js │ └── xhr.js ├── request │ ├── index.js │ └── request.js ├── index.js ├── router │ └── index.js └── dom │ └── index.js ├── static ├── menuBack.png ├── no-data.png ├── music │ ├── loop.png │ ├── next.png │ ├── once.png │ ├── play.png │ ├── prev.png │ ├── pause.png │ ├── random.png │ ├── music-bg.jpg │ ├── border-night.png │ ├── music-icon.png │ ├── music-list.png │ ├── music-type.png │ └── border-default.png └── cover │ ├── cover_1.png │ ├── cover_2.png │ ├── cover_3.png │ ├── cover_4.png │ ├── cover_5.png │ ├── cover_6.png │ └── cover_default.jpg ├── android ├── assets │ ├── logo.png │ └── splash.png └── com │ └── itstudy │ └── io │ ├── GetDirectoryList.java │ ├── GetExtSDCardPathList.java │ └── GetText.java ├── assets └── js │ ├── index.js │ └── config.js ├── nativeplugins └── YingBingNativePlugin │ ├── android │ └── uniplugin_yingbing-release.aar │ └── package.json ├── uni_modules └── yingbing-ReadPage │ ├── node_modules │ └── @better-scroll │ │ ├── pull-down │ │ ├── dist │ │ │ └── types │ │ │ │ ├── propertiesConfig.d.ts │ │ │ │ └── index.d.ts │ │ ├── README_zh-CN.md │ │ ├── README.md │ │ ├── src │ │ │ └── propertiesConfig.ts │ │ ├── LICENSE │ │ └── package.json │ │ ├── pull-up │ │ ├── dist │ │ │ ├── types │ │ │ │ ├── propertiesConfig.d.ts │ │ │ │ └── index.d.ts │ │ │ └── pull-up.min.js │ │ ├── README_zh-CN.md │ │ ├── README.md │ │ ├── src │ │ │ ├── propertiesConfig.ts │ │ │ └── index.ts │ │ ├── LICENSE │ │ └── package.json │ │ └── core │ │ ├── dist │ │ └── types │ │ │ ├── utils │ │ │ ├── typesHelper.d.ts │ │ │ ├── compare.d.ts │ │ │ ├── compat.d.ts │ │ │ └── bubbling.d.ts │ │ │ ├── index.d.ts │ │ │ ├── animater │ │ │ ├── Animation.d.ts │ │ │ ├── index.d.ts │ │ │ ├── Transition.d.ts │ │ │ └── Base.d.ts │ │ │ ├── scroller │ │ │ ├── createOptions.d.ts │ │ │ ├── DirectionLock.d.ts │ │ │ ├── Actions.d.ts │ │ │ ├── Behavior.d.ts │ │ │ └── Scroller.d.ts │ │ │ ├── translater │ │ │ └── index.d.ts │ │ │ ├── Instance.d.ts │ │ │ ├── base │ │ │ └── ActionsHandler.d.ts │ │ │ ├── BScroll.d.ts │ │ │ └── Options.d.ts │ │ ├── src │ │ ├── utils │ │ │ ├── typesHelper.ts │ │ │ ├── compare.ts │ │ │ ├── __tests__ │ │ │ │ └── bubbling.spec.ts │ │ │ ├── bubbling.ts │ │ │ └── compat.ts │ │ ├── index.ts │ │ ├── translater │ │ │ ├── __mocks__ │ │ │ │ └── index.ts │ │ │ ├── __tests__ │ │ │ │ └── index.spec.ts │ │ │ └── index.ts │ │ ├── animater │ │ │ ├── __mocks__ │ │ │ │ ├── index.ts │ │ │ │ ├── Animation.ts │ │ │ │ └── Transition.ts │ │ │ ├── index.ts │ │ │ ├── __tests__ │ │ │ │ └── index.spec.ts │ │ │ ├── Base.ts │ │ │ ├── Animation.ts │ │ │ └── Transition.ts │ │ ├── scroller │ │ │ ├── __mocks__ │ │ │ │ ├── DirectionLock.ts │ │ │ │ ├── Actions.ts │ │ │ │ ├── Behavior.ts │ │ │ │ └── Scroller.ts │ │ │ ├── createOptions.ts │ │ │ ├── __tests__ │ │ │ │ ├── createOptions.spec.ts │ │ │ │ ├── DirectionLock.spec.ts │ │ │ │ └── Behavior.spec.ts │ │ │ └── DirectionLock.ts │ │ ├── base │ │ │ └── __mocks__ │ │ │ │ └── ActionsHandler.ts │ │ ├── __mocks__ │ │ │ ├── Options.ts │ │ │ └── index.ts │ │ ├── __tests__ │ │ │ ├── __utils__ │ │ │ │ ├── event.ts │ │ │ │ └── layout.ts │ │ │ └── index.spec.ts │ │ └── Instance.ts │ │ ├── README_zh-CN.md │ │ ├── README.md │ │ ├── LICENSE │ │ └── package.json │ ├── components │ └── page-refresh │ │ └── page-refresh.vue │ ├── changelog.md │ └── package.json ├── main.js ├── common └── mixin │ ├── app.js │ ├── cache.js │ ├── bookcertify.js │ ├── musiccertify.js │ ├── music.js │ ├── book.js │ ├── lyric.js │ └── index.js ├── store ├── index.js ├── modules │ ├── app.js │ ├── cache.js │ ├── bookcertify.js │ ├── musiccertify.js │ ├── skin.js │ └── music.js └── config.js ├── components ├── gap-bar │ └── gap-bar.nvue ├── bubble-item │ └── bubble-item.nvue ├── no-data │ └── no-data.nvue ├── loading │ └── loading.nvue ├── crosswise │ └── crosswise.nvue ├── music-lyric │ └── music-lyric.nvue ├── fixed-button │ └── fixed-button.nvue ├── search │ └── search.nvue ├── c-switch │ └── c-switch.nvue ├── c-button │ └── c-button.nvue ├── comic-image │ └── comic-image.nvue ├── nav-bar │ └── nav-bar.nvue ├── bubble │ └── bubble.nvue └── list-scroll │ └── list-scroll.nvue ├── readme.md ├── package.json ├── App.vue ├── pages └── about │ └── index.nvue ├── changelog.md ├── modules ├── actionSheet.nvue ├── confirm.nvue └── edit.nvue └── pages.json /plugins/xhr/index.js: -------------------------------------------------------------------------------- 1 | import Xhr from './xhr.js' 2 | const xhr = new Xhr(); 3 | export default xhr; -------------------------------------------------------------------------------- /static/menuBack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/menuBack.png -------------------------------------------------------------------------------- /static/no-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/no-data.png -------------------------------------------------------------------------------- /static/music/loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/loop.png -------------------------------------------------------------------------------- /static/music/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/next.png -------------------------------------------------------------------------------- /static/music/once.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/once.png -------------------------------------------------------------------------------- /static/music/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/play.png -------------------------------------------------------------------------------- /static/music/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/prev.png -------------------------------------------------------------------------------- /android/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/android/assets/logo.png -------------------------------------------------------------------------------- /plugins/request/index.js: -------------------------------------------------------------------------------- 1 | import Http from './request.js' 2 | const http = new Http(); 3 | export default http; -------------------------------------------------------------------------------- /static/cover/cover_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_1.png -------------------------------------------------------------------------------- /static/cover/cover_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_2.png -------------------------------------------------------------------------------- /static/cover/cover_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_3.png -------------------------------------------------------------------------------- /static/cover/cover_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_4.png -------------------------------------------------------------------------------- /static/cover/cover_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_5.png -------------------------------------------------------------------------------- /static/cover/cover_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_6.png -------------------------------------------------------------------------------- /static/music/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/pause.png -------------------------------------------------------------------------------- /static/music/random.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/random.png -------------------------------------------------------------------------------- /android/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/android/assets/splash.png -------------------------------------------------------------------------------- /static/music/music-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/music-bg.jpg -------------------------------------------------------------------------------- /static/music/border-night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/border-night.png -------------------------------------------------------------------------------- /static/music/music-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/music-icon.png -------------------------------------------------------------------------------- /static/music/music-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/music-list.png -------------------------------------------------------------------------------- /static/music/music-type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/music-type.png -------------------------------------------------------------------------------- /static/cover/cover_default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/cover/cover_default.jpg -------------------------------------------------------------------------------- /static/music/border-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/static/music/border-default.png -------------------------------------------------------------------------------- /assets/js/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Utils from './util.js'; 3 | import Config from './config.js'; 4 | 5 | Vue.prototype.$utils = Utils; 6 | Vue.prototype.$config = Config; -------------------------------------------------------------------------------- /nativeplugins/YingBingNativePlugin/android/uniplugin_yingbing-release.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yingbing-developer/uni-reader/HEAD/nativeplugins/YingBingNativePlugin/android/uniplugin_yingbing-release.aar -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/dist/types/propertiesConfig.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: { 2 | key: string; 3 | sourceKey: string; 4 | }[]; 5 | export default _default; 6 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/dist/types/propertiesConfig.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: { 2 | key: string; 3 | sourceKey: string; 4 | }[]; 5 | export default _default; 6 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/typesHelper.d.ts: -------------------------------------------------------------------------------- 1 | export declare type UnionToIntersection = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never; 2 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/typesHelper.ts: -------------------------------------------------------------------------------- 1 | export type UnionToIntersection = ( 2 | U extends any ? (k: U) => void : never 3 | ) extends (k: infer I) => void 4 | ? I 5 | : never 6 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/compare.d.ts: -------------------------------------------------------------------------------- 1 | import { TranslaterPoint } from '../translater'; 2 | export declare function isSamePoint(startPoint: TranslaterPoint, endPoint: TranslaterPoint): boolean; 3 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/README_zh-CN.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/core 2 | 3 | 核心滚动,实现基础的列表滚动效果。 4 | 5 | ## 使用 6 | 7 | ```js 8 | import BScroll from '@better-scroll/core' 9 | 10 | const bs = new BScroll('.wrapper', {/* ... */}) 11 | ``` 12 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App' 3 | import store from './store'//引入vuex 4 | import '@/plugins' 5 | import '@/assets/js' 6 | 7 | Vue.config.productionTip = false 8 | 9 | App.mpType = 'app' 10 | 11 | const app = new Vue({ 12 | ...App, 13 | store 14 | }) 15 | app.$mount() 16 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/compat.d.ts: -------------------------------------------------------------------------------- 1 | import { TranslaterPoint } from '../translater'; 2 | declare type Position = { 3 | x: number; 4 | y: number; 5 | }; 6 | export declare const isValidPostion: (startPoint: TranslaterPoint, endPoint: TranslaterPoint, currentPos: Position, prePos: Position) => boolean; 7 | export {}; 8 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/README_zh-CN.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/pull-up 2 | 3 | 为 BetterScroll 注入上拉加载的能力。 4 | 5 | ## 使用 6 | 7 | ```js 8 | import BScroll from '@better-scroll/core' 9 | import Pullup from '@better-scroll/pull-up' 10 | BScroll.use(Pullup) 11 | 12 | const bs = new BScroll('.wrapper', { 13 | pullUpLoad: true 14 | }) 15 | ``` 16 | -------------------------------------------------------------------------------- /common/mixin/app.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const appMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | getAdult: 'app/getAdult', 6 | getAdultPwd: 'app/getAdultPwd' 7 | }) 8 | }, 9 | methods: { 10 | ...mapMutations({ 11 | setAdult: 'app/setAdult', 12 | setAdultPwd: 'app/setAdultPwd' 13 | }) 14 | } 15 | } 16 | 17 | export default appMixin; -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/README.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/core 2 | 3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/core/README_zh-CN.md) 4 | 5 | core scroll from BetterScroll. 6 | 7 | ## Usage 8 | 9 | ```js 10 | import BScroll from '@better-scroll/core' 11 | 12 | const bs = new BScroll('.wrapper', {/* ... */}) 13 | ``` 14 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/README_zh-CN.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/pull-down 2 | 3 | 为 BetterScroll 注入下拉刷新的能力。 4 | 5 | ## 使用 6 | 7 | ```js 8 | import BScroll from '@better-scroll/core' 9 | import Pulldown from '@better-scroll/pull-down' 10 | BScroll.use(Pulldown) 11 | 12 | const bs = new BScroll('.wrapper', { 13 | pullDownRefresh: true 14 | }) 15 | ``` 16 | -------------------------------------------------------------------------------- /plugins/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import { Route } from '@/plugins/router/router.js'; 3 | import Router from '@/plugins/router'; 4 | import Http from '@/plugins/request' 5 | import Xhr from '@/plugins/xhr' 6 | import Dom from '@/plugins/dom' 7 | Vue.prototype.$http = Http; 8 | Vue.prototype.$xhr = Xhr; 9 | Vue.prototype.$dom = Dom; 10 | Vue.prototype.$Router = Router; 11 | Vue.prototype.$Route = new Route(); -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/utils/bubbling.d.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils'; 2 | interface BubblingEventMap { 3 | source: string; 4 | target: string; 5 | } 6 | declare type BubblingEventConfig = BubblingEventMap | string; 7 | export declare function bubbling(source: EventEmitter, target: EventEmitter, events: BubblingEventConfig[]): void; 8 | export {}; 9 | -------------------------------------------------------------------------------- /common/mixin/cache.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const cacheMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | imageCache: 'cache/getImageCache' 6 | }) 7 | }, 8 | methods: { 9 | ...mapMutations({ 10 | addImageCache: 'cache/addImageCache', 11 | removeImageCache: 'cache/removeImageCache', 12 | clearImageCache: 'cache/clearImageCache' 13 | }) 14 | } 15 | } 16 | 17 | export default cacheMixin; -------------------------------------------------------------------------------- /plugins/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import Router from './router.js'; 3 | 4 | const guard = new Router(); 5 | /** 6 | * 路由前置守卫 7 | */ 8 | guard.beforeEach((to, from, next) => { 9 | next(); 10 | }); 11 | 12 | 13 | /** 14 | * 路由后置守卫 15 | */ 16 | guard.afterEach((to, from) => { 17 | }); 18 | 19 | 20 | /** 21 | * 报错钩子 22 | */ 23 | guard.onError((errMsg) => { 24 | console.log('my route-guards error: ' + errMsg); 25 | }); 26 | export default guard; -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import { BScroll } from './BScroll'; 2 | export { BScrollInstance } from './Instance'; 3 | export { Options, CustomOptions } from './Options'; 4 | export { TranslaterPoint } from './translater'; 5 | export { MountedBScrollHTMLElement } from './BScroll'; 6 | export { Behavior, Boundary } from './scroller/Behavior'; 7 | export { createBScroll, CustomAPI } from './BScroll'; 8 | export default BScroll; 9 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/compare.ts: -------------------------------------------------------------------------------- 1 | import { TranslaterPoint } from '../translater' 2 | 3 | export function isSamePoint( 4 | startPoint: TranslaterPoint, 5 | endPoint: TranslaterPoint 6 | ): boolean { 7 | // keys of startPoint and endPoint should be equal 8 | const keys = Object.keys(startPoint) 9 | for (let key of keys) { 10 | if (startPoint[key] !== endPoint[key]) return false 11 | } 12 | return true 13 | } 14 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Animation.d.ts: -------------------------------------------------------------------------------- 1 | import Base from './Base'; 2 | import { TranslaterPoint } from '../translater'; 3 | import { EaseFn } from '@better-scroll/shared-utils'; 4 | export default class Animation extends Base { 5 | move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easingFn: EaseFn | string): void; 6 | private animate; 7 | doStop(): boolean; 8 | stop(): void; 9 | } 10 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import { BScroll } from './BScroll' 2 | 3 | export { BScrollInstance } from './Instance' 4 | export { Options, CustomOptions } from './Options' 5 | export { TranslaterPoint } from './translater' 6 | export { MountedBScrollHTMLElement } from './BScroll' 7 | export { Behavior, Boundary } from './scroller/Behavior' 8 | export { createBScroll, CustomAPI } from './BScroll' 9 | 10 | export default BScroll 11 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/index.d.ts: -------------------------------------------------------------------------------- 1 | import Translater from '../translater'; 2 | import { Options as BScrollOptions } from '../Options'; 3 | import Animater from './Base'; 4 | import Transition from './Transition'; 5 | import Animation from './Animation'; 6 | export { Animater, Transition, Animation }; 7 | export default function createAnimater(element: HTMLElement, translater: Translater, options: BScrollOptions): Transition | Animation; 8 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/README.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/pull-up 2 | 3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/pull-up/README_zh-CN.md) 4 | 5 | The ability to inject a pull-up load for BetterScroll. 6 | 7 | ## Usage 8 | 9 | ```js 10 | import BScroll from '@better-scroll/core' 11 | import PullUp from '@better-scroll/pull-up' 12 | BScroll.use(PullUp) 13 | 14 | const bs = new BScroll('.wrapper', { 15 | pullUpLoad: true 16 | }) 17 | ``` 18 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/README.md: -------------------------------------------------------------------------------- 1 | # @better-scroll/pull-down 2 | 3 | [中文文档](https://github.com/ustbhuangyi/better-scroll/blob/master/packages/pull-down/README_zh-CN.md) 4 | 5 | The ability to inject a pull-down refresh for BetterScroll. 6 | 7 | ## Usage 8 | 9 | ```js 10 | import BScroll from '@better-scroll/core' 11 | import Pulldown from '@better-scroll/pull-down' 12 | BScroll.use(Pulldown) 13 | 14 | const bs = new BScroll('.wrapper', { 15 | pullDownRefresh: true 16 | }) 17 | ``` 18 | -------------------------------------------------------------------------------- /common/mixin/bookcertify.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const bookcertifyMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | bookInfo: 'bookcertify/getBookInfo', 6 | bookChapters: 'bookcertify/getBookChapters', 7 | pageInfo: 'bookcertify/getBookPageInfo' 8 | }) 9 | }, 10 | methods: { 11 | ...mapMutations({ 12 | setBookInfo: 'bookcertify/setBookInfo', 13 | setBookChapters: 'bookcertify/setBookChapters', 14 | setBookPageInfo: 'bookcertify/setBookPageInfo' 15 | }) 16 | } 17 | } 18 | 19 | export default bookcertifyMixin; -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/createOptions.d.ts: -------------------------------------------------------------------------------- 1 | import { Options as BScrollOptions } from '../Options'; 2 | import { Options as ActionsHandlerOptions } from '../base/ActionsHandler'; 3 | import { Options as BehaviorOptions, Bounces, Rect } from './Behavior'; 4 | export declare function createActionsHandlerOptions(bsOptions: BScrollOptions): ActionsHandlerOptions; 5 | export declare function createBehaviorOptions(bsOptions: BScrollOptions, extraProp: 'scrollX' | 'scrollY', bounces: Bounces, rect: Rect): BehaviorOptions; 6 | -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import book from './modules/book.js' 4 | import bookcertify from './modules/bookcertify.js' 5 | import music from './modules/music.js' 6 | import musiccertify from './modules/musiccertify.js' 7 | import skin from './modules/skin.js' 8 | import app from './modules/app.js' 9 | import cache from './modules/cache.js' 10 | Vue.use(Vuex) 11 | const store = new Vuex.Store({ 12 | modules: { 13 | book, 14 | bookcertify, 15 | music, 16 | musiccertify, 17 | skin, 18 | app, 19 | cache 20 | } 21 | }) 22 | export default store -------------------------------------------------------------------------------- /components/gap-bar/gap-bar.nvue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 27 | 28 | 31 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/__tests__/bubbling.spec.ts: -------------------------------------------------------------------------------- 1 | import { bubbling } from '../bubbling' 2 | import { EventEmitter } from '@better-scroll/shared-utils' 3 | 4 | describe('bubbling', () => { 5 | it('bubbling', () => { 6 | const parentHooks = new EventEmitter(['test']) 7 | const childHooks = new EventEmitter(['test']) 8 | bubbling(childHooks, parentHooks, ['test']) 9 | const handler = jest.fn(() => {}) 10 | parentHooks.on('test', handler) 11 | childHooks.trigger('test', 'dummy test') 12 | expect(handler).toBeCalledWith('dummy test') 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/__mocks__/index.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | const Translater = jest.fn().mockImplementation((content) => { 4 | return { 5 | style: content.style, 6 | hooks: new EventEmitter(['beforeTranslate', 'translate']), 7 | getComputedPosition: jest 8 | .fn() 9 | .mockImplementation((position = { x: 0, y: 0 }) => { 10 | return position 11 | }), 12 | translate: jest.fn(), 13 | destroy: jest.fn(), 14 | setContent: jest.fn(), 15 | } 16 | }) 17 | 18 | export default Translater 19 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/src/propertiesConfig.ts: -------------------------------------------------------------------------------- 1 | const sourcePrefix = 'plugins.pullUpLoad' 2 | 3 | const propertiesMap = [ 4 | { 5 | key: 'finishPullUp', 6 | name: 'finishPullUp' 7 | }, 8 | { 9 | key: 'openPullUp', 10 | name: 'openPullUp' 11 | }, 12 | { 13 | key: 'closePullUp', 14 | name: 'closePullUp' 15 | }, 16 | { 17 | key: 'autoPullUpLoad', 18 | name: 'autoPullUpLoad' 19 | } 20 | ] 21 | 22 | export default propertiesMap.map(item => { 23 | return { 24 | key: item.key, 25 | sourceKey: `${sourcePrefix}.${item.name}` 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/src/propertiesConfig.ts: -------------------------------------------------------------------------------- 1 | const sourcePrefix = 'plugins.pullDownRefresh' 2 | 3 | const propertiesMap = [ 4 | { 5 | key: 'finishPullDown', 6 | name: 'finishPullDown' 7 | }, 8 | { 9 | key: 'openPullDown', 10 | name: 'openPullDown' 11 | }, 12 | { 13 | key: 'closePullDown', 14 | name: 'closePullDown' 15 | }, 16 | { 17 | key: 'autoPullDownRefresh', 18 | name: 'autoPullDownRefresh' 19 | } 20 | ] 21 | 22 | export default propertiesMap.map(item => { 23 | return { 24 | key: item.key, 25 | sourceKey: `${sourcePrefix}.${item.name}` 26 | } 27 | }) 28 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/translater/index.d.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils'; 2 | export interface TranslaterPoint { 3 | x: number; 4 | y: number; 5 | [key: string]: number; 6 | } 7 | export default class Translater { 8 | content: HTMLElement; 9 | style: CSSStyleDeclaration; 10 | hooks: EventEmitter; 11 | constructor(content: HTMLElement); 12 | getComputedPosition(): { 13 | x: number; 14 | y: number; 15 | }; 16 | translate(point: TranslaterPoint): void; 17 | setContent(content: HTMLElement): void; 18 | destroy(): void; 19 | } 20 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Transition.d.ts: -------------------------------------------------------------------------------- 1 | import { EaseFn } from '@better-scroll/shared-utils'; 2 | import Base from './Base'; 3 | import { TranslaterPoint } from '../translater'; 4 | export default class Transition extends Base { 5 | startProbe(startPoint: TranslaterPoint, endPoint: TranslaterPoint): void; 6 | transitionTime(time?: number): void; 7 | transitionTimingFunction(easing: string): void; 8 | transitionProperty(): void; 9 | move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easingFn: string | EaseFn): void; 10 | doStop(): boolean; 11 | stop(): void; 12 | } 13 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/index.ts: -------------------------------------------------------------------------------- 1 | import Transition from '../Transition' 2 | import Animation from '../Animation' 3 | 4 | jest.mock('../Transition') 5 | jest.mock('../Animation') 6 | 7 | const createAnimater = jest 8 | .fn() 9 | .mockImplementation((element, translater, bscrollOptions) => { 10 | if (bscrollOptions.useTransition) { 11 | return new Transition(element, translater, bscrollOptions as { 12 | probeType: number 13 | }) 14 | } else { 15 | return new Animation(element, translater, bscrollOptions as { 16 | probeType: number 17 | }) 18 | } 19 | }) 20 | 21 | export default createAnimater 22 | -------------------------------------------------------------------------------- /store/modules/app.js: -------------------------------------------------------------------------------- 1 | import { ADULT, ADULTPWD } from '../config.js' 2 | 3 | const state = { 4 | adult: uni.getStorageSync(ADULT) || false, //青壮年模式 5 | adultPwd: uni.getStorageSync(ADULTPWD) || '' //青壮年模式密码 6 | } 7 | 8 | const getters = { 9 | getAdult (state) { 10 | return state.adult 11 | }, 12 | getAdultPwd (state) { 13 | return state.adultPwd 14 | } 15 | } 16 | 17 | const mutations = { 18 | setAdult (state, bol) { 19 | state.adult = bol; 20 | uni.setStorageSync(ADULT, bol) 21 | }, 22 | setAdultPwd (state, pwd) { 23 | state.adultPwd = pwd; 24 | uni.setStorageSync(ADULTPWD, pwd) 25 | } 26 | } 27 | 28 | export default { 29 | namespaced: true, 30 | state, 31 | getters, 32 | mutations 33 | } -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/DirectionLock.ts: -------------------------------------------------------------------------------- 1 | const DirectionLock = jest 2 | .fn() 3 | .mockImplementation((content, bscrollOptions) => { 4 | return { 5 | directionLocked: '', 6 | directionLockThreshold: '5', 7 | eventPassthrough: '', 8 | freeScroll: false, 9 | reset: jest.fn(), 10 | checkMovingDirection: jest.fn().mockImplementation((ret = true) => { 11 | return ret 12 | }), 13 | adjustDelta: jest 14 | .fn() 15 | .mockImplementation((deltaX: number = 0, deltaY: number = 0) => { 16 | return { 17 | deltaX, 18 | deltaY, 19 | } 20 | }), 21 | } 22 | }) 23 | 24 | export default DirectionLock 25 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/DirectionLock.d.ts: -------------------------------------------------------------------------------- 1 | import { TouchEvent, DirectionLock } from '@better-scroll/shared-utils'; 2 | export default class DirectionLockAction { 3 | directionLockThreshold: number; 4 | freeScroll: boolean; 5 | eventPassthrough: string; 6 | directionLocked: DirectionLock; 7 | constructor(directionLockThreshold: number, freeScroll: boolean, eventPassthrough: string); 8 | reset(): void; 9 | checkMovingDirection(absDistX: number, absDistY: number, e: TouchEvent): boolean; 10 | adjustDelta(deltaX: number, deltaY: number): { 11 | deltaX: number; 12 | deltaY: number; 13 | }; 14 | private computeDirectionLock; 15 | private handleEventPassthrough; 16 | } 17 | -------------------------------------------------------------------------------- /components/bubble-item/bubble-item.nvue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | 25 | 36 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/base/__mocks__/ActionsHandler.ts: -------------------------------------------------------------------------------- 1 | import { EventRegister, EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | const ActionsHandler = jest 4 | .fn() 5 | .mockImplementation((wrapper, bscrollOptions) => { 6 | return { 7 | wrapper, 8 | options: bscrollOptions, 9 | initiated: 1, 10 | pointX: 0, 11 | pointY: 0, 12 | startClickRegister: new EventRegister(wrapper, []), 13 | moveEndRegister: new EventRegister(wrapper, []), 14 | hooks: new EventEmitter(['beforeStart', 'start', 'move', 'end', 'click']), 15 | destroy: jest.fn(), 16 | setInitiated: jest.fn(), 17 | setContent: jest.fn(), 18 | rebindDOMEvents: jest.fn(), 19 | } 20 | }) 21 | 22 | export default ActionsHandler 23 | -------------------------------------------------------------------------------- /common/mixin/musiccertify.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const musiccertifyMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | musicInfo: 'musiccertify/getMusicInfo', 6 | getMusicPlayStatus: 'musiccertify/getMusicPlayStatus', 7 | getMusicPlayTime: 'musiccertify/getMusicPlayTime', 8 | getMusicPlayDuration: 'musiccertify/getMusicPlayDuration', 9 | getMusicLyric: 'musiccertify/getMusicLyric' 10 | }) 11 | }, 12 | methods: { 13 | ...mapMutations({ 14 | setMusicInfo: 'musiccertify/setMusicInfo', 15 | setMusicPlayStatus: 'musiccertify/setMusicPlayStatus', 16 | setMusicPlayTime: 'musiccertify/setMusicPlayTime', 17 | setMusicPlayDuration: 'musiccertify/setMusicPlayDuration', 18 | setMusicLyric: 'musiccertify/setMusicLyric' 19 | }) 20 | } 21 | } 22 | 23 | export default musiccertifyMixin; -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/bubbling.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | interface BubblingEventMap { 4 | source: string 5 | target: string 6 | } 7 | type BubblingEventConfig = BubblingEventMap | string 8 | export function bubbling( 9 | source: EventEmitter, 10 | target: EventEmitter, 11 | events: BubblingEventConfig[] 12 | ) { 13 | events.forEach(event => { 14 | let sourceEvent: string 15 | let targetEvent: string 16 | if (typeof event === 'string') { 17 | sourceEvent = targetEvent = event 18 | } else { 19 | sourceEvent = event.source 20 | targetEvent = event.target 21 | } 22 | source.on(sourceEvent, function(...args: any[]) { 23 | return target.trigger(targetEvent, ...args) 24 | }) 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /components/no-data/no-data.nvue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 22 | 23 | 42 | -------------------------------------------------------------------------------- /store/modules/cache.js: -------------------------------------------------------------------------------- 1 | import { IMAGECACHE } from '../config.js' 2 | 3 | const state = { 4 | imageCache: uni.getStorageSync(IMAGECACHE) || [] //图片临时文件存放 5 | } 6 | 7 | const getters = { 8 | getImageCache (state) { 9 | return state.imageCache 10 | } 11 | } 12 | 13 | const mutations = { 14 | addImageCache (state, obj) { 15 | state.imageCache.push(obj); 16 | uni.setStorageSync(IMAGECACHE, state.imageCache) 17 | }, 18 | removeImageCache (state, key) { 19 | const index = state.imageCache.findIndex(item => item.key == key) 20 | if ( index > -1 ) state.imageCache.splice(index, 1); 21 | uni.setStorageSync(IMAGECACHE, state.imageCache) 22 | }, 23 | clearImageCache (state) { 24 | uni.removeStorageSync(IMAGECACHE) 25 | } 26 | } 27 | 28 | export default { 29 | namespaced: true, 30 | state, 31 | getters, 32 | mutations 33 | } -------------------------------------------------------------------------------- /store/modules/bookcertify.js: -------------------------------------------------------------------------------- 1 | //书籍临时阅读数据 2 | import Utils from '@/assets/js/util.js'; 3 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils; 4 | const state = { 5 | bookInfo: '',//当前阅读书籍信息 6 | bookChapters: [],//当前阅读书籍章节列表 7 | bookPageInfo: ''//当前阅读页面信息 8 | } 9 | 10 | const getters = { 11 | getBookInfo (state) { 12 | return state.bookInfo; 13 | }, 14 | getBookChapters (state) { 15 | return state.bookChapters; 16 | }, 17 | getBookPageInfo (state) { 18 | return state.bookPageInfo; 19 | } 20 | } 21 | 22 | const mutations = { 23 | setBookInfo (state, bookInfo) { 24 | state.bookInfo = bookInfo 25 | }, 26 | setBookChapters (state, chapters) { 27 | state.bookChapters = chapters 28 | }, 29 | setBookPageInfo (state, pageInfo) { 30 | state.bookPageInfo = JSON.parse(JSON.stringify(pageInfo)) 31 | } 32 | } 33 | 34 | export default { 35 | namespaced: true, 36 | state, 37 | getters, 38 | mutations 39 | } -------------------------------------------------------------------------------- /common/mixin/music.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const musicMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | playList: 'music/playList', 6 | musicPathHistory: 'music/musicPathHistory', 7 | getMusicPlayMode: 'music/getMusicPlayMode', 8 | getMusicPlayRecord: 'music/getMusicPlayRecord', 9 | getMusicLyricShow: 'music/getMusicLyricShow', 10 | getMusicSourcesController: 'music/getMusicSourcesController' 11 | }) 12 | }, 13 | methods: { 14 | ...mapMutations({ 15 | addMusic: 'music/addMusic', 16 | deleteMusic: 'music/deleteMusic', 17 | clearMusic: 'music/clearMusic', 18 | updateMusicPlayRecord: 'music/updateMusicPlayRecord', 19 | changeMusicPlayMode: 'music/changeMusicPlayMode', 20 | setMusicLyricShow: 'music/setMusicLyricShow', 21 | updateMusicPath: 'music/updateMusicPath', 22 | setMusicSourcesController: 'music/setMusicSourcesController' 23 | }) 24 | } 25 | } 26 | 27 | export default musicMixin; -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | #使用须知 2 | 3 | * 1、这个项目只支持android app端,因为没有会IOS的同事,且没有苹果手机 4 | * 2、请注意压缩包中有个android文件夹,里面放的是原生插件,具体是做什么用的,方法里面已经写好了 5 | * 3、请注意压缩包中的原生插件,只是普通的java文件,不是打包好的插件,只能用离线打包的方式使用,需要下载官方的离线SDK包,使用方法见这个帖子:[uniapp直接调用安卓自定义方法](https://ask.dcloud.net.cn/article/36065) 6 | * 4、现在将获取本地小说文本内容的原生方法封装成了插件,同时获取文件列表的方法也使用native.js方法获取,如果你不需要阅读本地漫画,就可以直接云打包 7 | * 5、如果只是想体验下的朋友,可以直接运行使用,项目中有为了调试而写的方法,只是性能不如原生插件,只能调试用,根据情况选择就行,方法都是注释好了的(调试用方法已经没有了,现在读取本地小说内容只有原生方法了) 8 | * 6、小说翻页方式包括(左右滑动,上下滑动,点击翻页, 伪·仿真翻页,覆盖翻页);漫画翻页方式只有上下滚动 9 | * 7、以nvue的list组件为基础写了个列表滚动组件,做了虚拟列表优化,不过效果不是很好, 白屏时间较长 10 | * 8、首页的拖曳菜单,效果不是很好,有些bug,能力有限,只能写成这样,期望有大佬能告知更好的实现方法 11 | * 9、如果想要使用原生方法调试也可以本地制作自定义基座,以自定义基座的方式来运行,本地制作自定义基座的方法与本地打包的方法类似,具体见这里:[uni本地打包android自定义基座](https://www.cnblogs.com/fdxjava/articles/13354591.html) 12 | * 10、获取扩展TF卡路径的方法只有原生,如果不需要可以删掉 13 | * 11、音乐播放只支持应用内播放,不支持后台播放(经过测试某些手机后台也能继续播放) 14 | * 12、在线小说、漫画和音乐的接口仅供学习使用,请不要拿来做商业活动,也请不要随意攻击别人的网站,因此而造成的后果,请自己承担 15 | * 13、在线小说和漫画有个接口部分网络访问有问题,我家里的电信宽带可以访问,但手机的移动网络无法访问 16 | * 14、如果有什么问题都可以说 -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/Animation.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | const Animation = jest 4 | .fn() 5 | .mockImplementation((content, translater, bscrollOptions) => { 6 | return { 7 | content, 8 | translater, 9 | options: bscrollOptions, 10 | style: content.style, 11 | pending: false, 12 | forceStopped: false, 13 | timer: 0, 14 | hooks: new EventEmitter([ 15 | 'move', 16 | 'end', 17 | 'forceStop', 18 | 'beforeForceStop', 19 | 'callStop', 20 | 'time', 21 | 'timeFunction', 22 | ]), 23 | translate: jest.fn(), 24 | stop: jest.fn(), 25 | doStop: jest.fn(), 26 | move: jest.fn(), 27 | destroy: jest.fn(), 28 | setPending: jest.fn(), 29 | setForceStopped: jest.fn(), 30 | setCallStop: jest.fn(), 31 | setContent: jest.fn(), 32 | clearTimer: jest.fn(), 33 | } 34 | }) 35 | 36 | export default Animation 37 | -------------------------------------------------------------------------------- /assets/js/config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | //小说网站链接 3 | BOOKURL: { 4 | 'baoshuu': { 5 | title: '手机宝书', 6 | href: 'http://m.baoshuu.com' 7 | } 8 | }, 9 | 10 | //漫画网站链接 11 | COMICURL: { 12 | 'mangabz': { 13 | title: 'mangaBz', 14 | href: 'http://www.mangabz.com' 15 | }, 16 | 'sixmh': { 17 | title: '6漫画', 18 | href: 'http://m.sixmh7.com' 19 | }, 20 | 'dmzj': { 21 | title: '动漫之家', 22 | href: 'https://www.dmzj.com' 23 | } 24 | }, 25 | //音乐网站链接 26 | MUSICURL: { 27 | 'qqmusic': { 28 | title: 'QQ音乐', 29 | href: 'https://c.y.qq.com' 30 | }, 31 | '163music': { 32 | title: '网易云音乐', 33 | href: 'https://autumnfish.cn' 34 | } 35 | }, 36 | 37 | //青壮年内容 38 | ADULTS: [], 39 | 40 | //QQ音乐请求常量 41 | commonParams: { 42 | g_tk: 5381, 43 | loginUin: 0, 44 | hostUin: 0, 45 | format: 'json', 46 | inCharset: 'utf8', 47 | outCharset: 'utf-8', 48 | notice: 0, 49 | platform: 'yqq.json', 50 | needNewCode: 0 51 | }, 52 | 53 | 54 | //请求成功编码 55 | ERR_OK: 200, 56 | //请求失败编码 57 | ERR_FALSE: 300, 58 | //请求超时时间 59 | TIMEOUT: 50000 60 | } 61 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/index.ts: -------------------------------------------------------------------------------- 1 | import Translater from '../translater' 2 | import { Options as BScrollOptions } from '../Options' 3 | 4 | import Animater from './Base' 5 | import Transition from './Transition' 6 | import Animation from './Animation' 7 | 8 | export { Animater, Transition, Animation } 9 | 10 | export default function createAnimater( 11 | element: HTMLElement, 12 | translater: Translater, 13 | options: BScrollOptions 14 | ) { 15 | const useTransition = options.useTransition 16 | let animaterOptions = {} 17 | Object.defineProperty(animaterOptions, 'probeType', { 18 | enumerable: true, 19 | configurable: false, 20 | get() { 21 | return options.probeType 22 | }, 23 | }) 24 | if (useTransition) { 25 | return new Transition( 26 | element, 27 | translater, 28 | animaterOptions as { 29 | probeType: number 30 | } 31 | ) 32 | } else { 33 | return new Animation( 34 | element, 35 | translater, 36 | animaterOptions as { 37 | probeType: number 38 | } 39 | ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__mocks__/Transition.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | const Transition = jest 4 | .fn() 5 | .mockImplementation((content, translater, bscrollOptions) => { 6 | return { 7 | content, 8 | translater, 9 | options: bscrollOptions, 10 | style: content.style, 11 | pending: false, 12 | forceStopped: false, 13 | timer: 0, 14 | hooks: new EventEmitter([ 15 | 'move', 16 | 'end', 17 | 'forceStop', 18 | 'beforeForceStop', 19 | 'callStop', 20 | 'time', 21 | 'timeFunction', 22 | ]), 23 | translate: jest.fn(), 24 | stop: jest.fn(), 25 | doStop: jest.fn(), 26 | move: jest.fn(), 27 | startProbe: jest.fn(), 28 | transitionTime: jest.fn(), 29 | transitionTimingFunction: jest.fn(), 30 | destroy: jest.fn(), 31 | setPending: jest.fn(), 32 | setForceStopped: jest.fn(), 33 | setCallStop: jest.fn(), 34 | setContent: jest.fn(), 35 | clearTimer: jest.fn(), 36 | } 37 | }) 38 | 39 | export default Transition 40 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 HuangYi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/components/page-refresh/page-refresh.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 27 | 28 | 52 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 HuangYi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 HuangYi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /nativeplugins/YingBingNativePlugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "YingBingNativePlugin", 3 | "id": "YingBingNativePlugin", 4 | "version": "1.0", 5 | "description": "个人原生插件集合(获取txt文件内容,处理防盗链图片)", 6 | "_dp_type":"nativeplugin", 7 | "_dp_nativeplugin":{ 8 | "android": { 9 | "plugins": [ 10 | { 11 | "type": "module", 12 | "name": "YingBingNativePlugin-Reader", 13 | "class": "com.yingbing.nativeplugin.Reader" 14 | }, 15 | { 16 | "type": "module", 17 | "name": "YingBingNativePlugin-BaseImage", 18 | "class": "com.yingbing.nativeplugin.BaseImage" 19 | } 20 | ], 21 | "hooksClass": "", 22 | "integrateType": "aar", 23 | "dependencies": [ 24 | ], 25 | "compileOptions": { 26 | "sourceCompatibility": "1.8", 27 | "targetCompatibility": "1.8" 28 | }, 29 | "abis": [ 30 | "armeabi-v7a", 31 | "x86" 32 | ], 33 | "minSdkVersion": "22", 34 | "permissions": [ 35 | ], 36 | "parameters": { 37 | "android_appid": { 38 | "des": "请填写appid", 39 | "key": "TM123456", 40 | "placeholder": "" 41 | } 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /store/config.js: -------------------------------------------------------------------------------- 1 | export const SKIN = 'UNI_READER_SKIN'//皮肤 2 | export const ADULT = 'UNI_READER_ADULT'//青壮年模式 3 | export const ADULTPWD = 'UNI_READER_ADULT_PWD'//青壮年模式密码 4 | export const BOOKS = 'UNI_READER_BOOK_LIST'//书籍列表 5 | export const BOOKPATH = 'UNI_READER_BOOK_PATH'//上次访问小说存放路径 6 | export const BOOKREAD = 'UNI_READER_BOOK_READ'//小说阅读模式 7 | export const BOOKMARK = 'UNI_READER_BOOK_MARK'//小说书签列表 8 | export const COMICPATH = 'UNI_READER_COMIC_PATH'//上次访问漫画存放路径 9 | export const COMICORIEN = 'UNI_READER_COMIC_ORIEN'//漫画阅读方向 10 | export const MUSICPATH = 'UNI_READER_MUSIC_PATH'//上次访问的本地音乐资源路径 11 | export const PLAYLIST = 'UNI_READER_MUSIC_PLAY_LIST'//音乐播放列表 12 | export const PLAYSTATUS = 'UNI_READER_MUSIC_PLAY_STATUS'//音乐播放状态 13 | export const PLAYMODE = 'UNI_READER_MUSIC_PLAY_MODE'//音乐播放模式 14 | export const PLAYRECORD = 'UNI_READER_MUSIC_PLAY_RECORD'//音乐播放记录 15 | export const COMICSOURCES = 'UNI_READER_ONLINE_COMIC_SOURCES'//在线漫画来源控制,放进来的表示关闭获取此来源的漫画 16 | export const MUSICSOURCES = 'UNI_READER_ONLINE_MUSIC_SOURCES'//在线音乐来源控制,放进来的表示关闭获取此来源的音乐 17 | export const BOOKSOURCES = 'UNI_READER_ONLINE_BOOK_SOURCES'//在线小说来源控制,放进来的表示关闭获取此来源的漫画 18 | export const MUSICLYRICSHOW = 'UNI_READER_ONLINE_MUSIC_LYRIC_SHOW'//控制歌词显示 19 | export const IMAGECACHE = 'UNI_READER_IMAGE_CACHE'//图片缓存 -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/changelog.md: -------------------------------------------------------------------------------- 1 | ## 1.2.4(2021-10-18) 2 | * 修复滚动模式定位问题 3 | ## 1.2.3(2021-10-17) 4 | * 添加点击区域配置,具体见下面得介绍 5 | ## 1.2.2(2021-10-17) 6 | * 优化滚动模式 7 | ## 1.2.1(2021-10-15) 8 | * 优化滚动模式逻辑 9 | ## 1.2.0(2021-10-15) 10 | * 修复滚动模式下得问题 11 | ## 1.1.9(2021-10-15) 12 | * 修复一些显示问题 13 | * 优化了一下滚动模式滚动效果 14 | ## 1.1.8(2021-10-14) 15 | * content对象中可以带上章节名称,方便取值 16 | * 增加初始化loading效果 17 | ## 1.1.7(2021-10-14) 18 | * 增加整书模式返回得页面信息 19 | ## 1.1.6(2021-10-14) 20 | * 更改整书模式返回章节集合得参数 21 | ## 1.1.5(2021-10-14) 22 | * 优化翻页得性能,同时最多显示3张页面 23 | ## 1.1.4(2021-10-13) 24 | 修复一些问题 25 | ## 1.1.3(2021-10-13) 26 | * 修复一些问题 27 | ## 1.1.2(2021-10-13) 28 | * 修复一些问题 29 | ## 1.1.1(2021-10-13) 30 | * 修复了一些问题 31 | ## 1.1.0(2021-10-12) 32 | * 此次更新为重构插件 33 | * 首先感谢一下2位插件使用者提供的反馈 34 | * 主要更新如下: 35 | - 1、为请求事件增加了过渡效果,滚动模式下增加上拉和下拉操作 36 | - 2、解决了一些逻辑问题,现在preload和loadmore事件触发更合理 37 | - 3、其它都是些小更新,比如章节模式下currentChange事件增加了返回的页面信息 38 | - 4、更改了参数结构,请注意阅读使用须知 39 | ## 1.0.5(2021-09-22) 40 | * 修复上次更新引起无法翻到上一页的问题 41 | ## 1.0.4(2021-09-22) 42 | * 修复横向翻页部分页面不绘制的bug 43 | ## 1.0.3(2021-09-05) 44 | * 修复整书模式下阅读小说到最后面,下一页会从小说最前面再次排版的bug 45 | ## 1.0.2(2021-09-04) 46 | * 修复预加载章节内容无效的问题 47 | * 添加初始化触发currentChange事件 48 | ## 1.0.1(2021-08-29) 49 | * 减少滚动模式下触底加载更多时的滚动距离 50 | ## 1.0.0(2021-08-28) 51 | * 发布1.0.0版本 52 | -------------------------------------------------------------------------------- /components/loading/loading.nvue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 54 | 55 | 58 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/Instance.d.ts: -------------------------------------------------------------------------------- 1 | import { Behavior } from './scroller/Behavior'; 2 | import Actions from './scroller/Actions'; 3 | import { ExposedAPI as ExposedAPIByScroller } from './scroller/Scroller'; 4 | import { Animater } from './animater'; 5 | import { ExposedAPI as ExposedAPIByAnimater } from './animater/Base'; 6 | export interface BScrollInstance extends ExposedAPIByScroller, ExposedAPIByAnimater { 7 | [key: string]: any; 8 | x: Behavior['currentPos']; 9 | y: Behavior['currentPos']; 10 | hasHorizontalScroll: Behavior['hasScroll']; 11 | hasVerticalScroll: Behavior['hasScroll']; 12 | scrollerWidth: Behavior['contentSize']; 13 | scrollerHeight: Behavior['contentSize']; 14 | maxScrollX: Behavior['maxScrollPos']; 15 | maxScrollY: Behavior['maxScrollPos']; 16 | minScrollX: Behavior['minScrollPos']; 17 | minScrollY: Behavior['minScrollPos']; 18 | movingDirectionX: Behavior['movingDirection']; 19 | movingDirectionY: Behavior['movingDirection']; 20 | directionX: Behavior['direction']; 21 | directionY: Behavior['direction']; 22 | enabled: Actions['enabled']; 23 | pending: Animater['pending']; 24 | } 25 | export declare const propertiesConfig: { 26 | sourceKey: string; 27 | key: string; 28 | }[]; 29 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import Translater from '../../translater/index' 2 | import Transition from '../Transition' 3 | import Animation from '../Animation' 4 | import { OptionsConstructor } from '../../Options' 5 | jest.mock('../Animation') 6 | jest.mock('../Transition') 7 | jest.mock('../Base') 8 | jest.mock('../../translater/index') 9 | jest.mock('../../Options') 10 | 11 | import createAnimater from '../index' 12 | 13 | describe('animater create test suit', () => { 14 | const dom = document.createElement('div') 15 | const translater = new Translater(dom) 16 | it('should create Transition class when useTransition=true', () => { 17 | const options = new OptionsConstructor() 18 | options.probeType = 0 19 | options.useTransition = true 20 | const animater = createAnimater(dom, translater, options) 21 | expect(Transition).toBeCalledWith(dom, translater, { probeType: 0 }) 22 | }) 23 | it('should create Animation class when useTransition=false', () => { 24 | const options = new OptionsConstructor() 25 | options.probeType = 0 26 | options.useTransition = false 27 | const animater = createAnimater(dom, translater, options) 28 | expect(Animation).toBeCalledWith(dom, translater, { probeType: 0 }) 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/base/ActionsHandler.d.ts: -------------------------------------------------------------------------------- 1 | import { EventRegister, EventEmitter } from '@better-scroll/shared-utils'; 2 | declare type Exception = { 3 | tagName?: RegExp; 4 | className?: RegExp; 5 | }; 6 | export interface Options { 7 | [key: string]: boolean | number | Exception; 8 | click: boolean; 9 | bindToWrapper: boolean; 10 | disableMouse: boolean; 11 | disableTouch: boolean; 12 | preventDefault: boolean; 13 | stopPropagation: boolean; 14 | preventDefaultException: Exception; 15 | tagException: Exception; 16 | autoEndDistance: number; 17 | } 18 | export default class ActionsHandler { 19 | wrapper: HTMLElement; 20 | options: Options; 21 | hooks: EventEmitter; 22 | initiated: number; 23 | pointX: number; 24 | pointY: number; 25 | wrapperEventRegister: EventRegister; 26 | targetEventRegister: EventRegister; 27 | constructor(wrapper: HTMLElement, options: Options); 28 | private handleDOMEvents; 29 | private beforeHandler; 30 | setInitiated(type?: number): void; 31 | private start; 32 | private move; 33 | private end; 34 | private click; 35 | setContent(content: HTMLElement): void; 36 | rebindDOMEvents(): void; 37 | destroy(): void; 38 | } 39 | export {}; 40 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import BScroll from '@better-scroll/core'; 2 | export declare type PullUpLoadOptions = Partial | true; 3 | export interface PullUpLoadConfig { 4 | threshold: number; 5 | } 6 | declare module '@better-scroll/core' { 7 | interface CustomOptions { 8 | pullUpLoad?: PullUpLoadOptions; 9 | } 10 | interface CustomAPI { 11 | pullUpLoad: PluginAPI; 12 | } 13 | } 14 | interface PluginAPI { 15 | finishPullUp(): void; 16 | openPullUp(config?: PullUpLoadOptions): void; 17 | closePullUp(): void; 18 | autoPullUpLoad(): void; 19 | } 20 | export default class PullUp implements PluginAPI { 21 | scroll: BScroll; 22 | static pluginName: string; 23 | private hooksFn; 24 | pulling: boolean; 25 | watching: boolean; 26 | options: PullUpLoadConfig; 27 | constructor(scroll: BScroll); 28 | private init; 29 | private handleBScroll; 30 | private handleOptions; 31 | private handleHooks; 32 | private registerHooks; 33 | private watch; 34 | private unwatch; 35 | private checkPullUp; 36 | finishPullUp(): void; 37 | openPullUp(config?: PullUpLoadOptions): void; 38 | closePullUp(): void; 39 | autoPullUpLoad(): void; 40 | } 41 | export {}; 42 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/animater/Base.d.ts: -------------------------------------------------------------------------------- 1 | import { EaseFn, safeCSSStyleDeclaration, EventEmitter } from '@better-scroll/shared-utils'; 2 | import Translater, { TranslaterPoint } from '../translater'; 3 | export interface ExposedAPI { 4 | stop(): void; 5 | } 6 | export default abstract class Base implements ExposedAPI { 7 | translater: Translater; 8 | options: { 9 | probeType: number; 10 | }; 11 | content: HTMLElement; 12 | style: safeCSSStyleDeclaration; 13 | hooks: EventEmitter; 14 | timer: number; 15 | pending: boolean; 16 | callStopWhenPending: boolean; 17 | forceStopped: boolean; 18 | _reflow: number; 19 | [key: string]: any; 20 | constructor(content: HTMLElement, translater: Translater, options: { 21 | probeType: number; 22 | }); 23 | translate(endPoint: TranslaterPoint): void; 24 | setPending(pending: boolean): void; 25 | setForceStopped(forceStopped: boolean): void; 26 | setCallStop(called: boolean): void; 27 | setContent(content: HTMLElement): void; 28 | clearTimer(): void; 29 | abstract move(startPoint: TranslaterPoint, endPoint: TranslaterPoint, time: number, easing: string | EaseFn): void; 30 | abstract doStop(): void; 31 | abstract stop(): void; 32 | destroy(): void; 33 | } 34 | -------------------------------------------------------------------------------- /store/modules/musiccertify.js: -------------------------------------------------------------------------------- 1 | //音乐播放临时阅读数据 2 | import Utils from '@/assets/js/util.js'; 3 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils; 4 | const state = { 5 | musicInfo: '',//当前播放音乐信息 6 | musicPlayStatus: false,//音乐播放状态 7 | musicPlayTime: 0,//当前音乐播放位置 8 | musicPlayDuration: 0,//当前音乐总时长 9 | musicLyric: [],//当前音乐歌词 10 | } 11 | 12 | const getters = { 13 | getMusicInfo (state) { 14 | return state.musicInfo; 15 | }, 16 | getMusicPlayStatus (state) { 17 | return state.musicPlayStatus 18 | }, 19 | getMusicPlayTime (state) { 20 | return state.musicPlayTime 21 | }, 22 | getMusicPlayDuration (state) { 23 | return state.musicPlayDuration 24 | }, 25 | getMusicLyric (state) { 26 | return state.musicLyric 27 | } 28 | } 29 | 30 | const mutations = { 31 | setMusicInfo (state, musicInfo) { 32 | state.musicInfo = musicInfo 33 | }, 34 | //设置音乐播放状态 35 | setMusicPlayStatus (state, status) { 36 | state.musicPlayStatus = status; 37 | }, 38 | //设置音乐播放时长 39 | setMusicPlayTime (state, time) { 40 | state.musicPlayTime = time; 41 | }, 42 | //设置音乐总时长 43 | setMusicPlayDuration (state, duration) { 44 | state.musicPlayDuration = duration; 45 | }, 46 | //设置音乐歌词 47 | setMusicLyric (state, lyric) { 48 | state.musicLyric = lyric; 49 | }, 50 | } 51 | 52 | export default { 53 | namespaced: true, 54 | state, 55 | getters, 56 | mutations 57 | } -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Actions.d.ts: -------------------------------------------------------------------------------- 1 | import ActionsHandler from '../base/ActionsHandler'; 2 | import { Behavior } from './Behavior'; 3 | import DirectionLockAction from './DirectionLock'; 4 | import { Animater } from '../animater'; 5 | import { OptionsConstructor as BScrollOptions } from '../Options'; 6 | import { TranslaterPoint } from '../translater'; 7 | import { EventEmitter } from '@better-scroll/shared-utils'; 8 | export default class ScrollerActions { 9 | hooks: EventEmitter; 10 | scrollBehaviorX: Behavior; 11 | scrollBehaviorY: Behavior; 12 | actionsHandler: ActionsHandler; 13 | animater: Animater; 14 | options: BScrollOptions; 15 | directionLockAction: DirectionLockAction; 16 | fingerMoved: boolean; 17 | contentMoved: boolean; 18 | enabled: boolean; 19 | startTime: number; 20 | endTime: number; 21 | ensuringInteger: boolean; 22 | constructor(scrollBehaviorX: Behavior, scrollBehaviorY: Behavior, actionsHandler: ActionsHandler, animater: Animater, options: BScrollOptions); 23 | private bindActionsHandler; 24 | private handleStart; 25 | private handleMove; 26 | private dispatchScroll; 27 | private checkMomentum; 28 | private handleEnd; 29 | private ensureIntegerPos; 30 | private handleClick; 31 | getCurrentPos(): TranslaterPoint; 32 | refresh(): void; 33 | destroy(): void; 34 | } 35 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/utils/compat.ts: -------------------------------------------------------------------------------- 1 | import { Direction } from '@better-scroll/shared-utils' 2 | import { TranslaterPoint } from '../translater' 3 | 4 | type Position = { 5 | x: number 6 | y: number 7 | } 8 | // iOS 13.6 - 14.x, window.getComputedStyle sometimes will get wrong transform value 9 | // when bs use transition mode 10 | // eg: translateY -100px -> -200px, when the last frame which is about to scroll to -200px 11 | // window.getComputedStyle(this.content) will calculate transformY to be -100px(startPoint) 12 | // it is weird 13 | // so we should validate position caculated by 'window.getComputedStyle' 14 | export const isValidPostion = ( 15 | startPoint: TranslaterPoint, 16 | endPoint: TranslaterPoint, 17 | currentPos: Position, 18 | prePos: Position 19 | ) => { 20 | const computeDirection = (endValue: number, startValue: number) => { 21 | const delta = endValue - startValue 22 | const direction = 23 | delta > 0 24 | ? Direction.Negative 25 | : delta < 0 26 | ? Direction.Positive 27 | : Direction.Default 28 | return direction 29 | } 30 | const directionX = computeDirection(endPoint.x, startPoint.x) 31 | const directionY = computeDirection(endPoint.y, startPoint.y) 32 | const deltaX = currentPos.x - prePos.x 33 | const deltaY = currentPos.y - prePos.y 34 | 35 | return directionX * deltaX <= 0 && directionY * deltaY <= 0 36 | } 37 | -------------------------------------------------------------------------------- /components/crosswise/crosswise.nvue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 52 | 53 | 62 | -------------------------------------------------------------------------------- /common/mixin/book.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | const bookMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | bookList: 'book/bookList', 6 | bookmarks: 'book/bookmarks', 7 | bookPathHistory: 'book/bookPathHistory', 8 | bookReadMode: 'book/bookReadMode', 9 | getBookSourcesController: 'book/getBookSourcesController', 10 | comicPathHistory: 'book/comicPathHistory', 11 | comicOrienMode: 'book/comicOrienMode', 12 | getComicSourcesController: 'book/getComicSourcesController', 13 | }) 14 | }, 15 | methods: { 16 | ...mapMutations({ 17 | addBooks: 'book/addBooks', 18 | deleteBook: 'book/deleteBook', 19 | clearBooks: 'book/clearBooks', 20 | updateBookInfo: 'book/updateBookInfo', 21 | updateBookPath: 'book/updateBookPath', 22 | changeBookFontSize: 'book/changeBookFontSize', 23 | changeBookReadPageType: 'book/changeBookReadPageType', 24 | changeBookReadLineHeight: 'book/changeBookReadLineHeight', 25 | changeBookLight: 'book/changeBookLight', 26 | saveBookmark: 'book/saveBookmark', 27 | clearBookmark: 'book/clearBookmark', 28 | setBookSourcesController: 'book/setBookSourcesController', 29 | setComicSourcesController: 'book/setComicSourcesController', 30 | updateComicPath: 'book/updateComicPath', 31 | clearComicPath: 'book/clearComicPath', 32 | changeComicOrien: 'book/changeComicOrien', 33 | setComicSourcesController: 'book/setComicSourcesController' 34 | }) 35 | } 36 | } 37 | 38 | export default bookMixin; -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Actions.ts: -------------------------------------------------------------------------------- 1 | import DirectionLock from '../DirectionLock' 2 | 3 | jest.mock('../DirectionLock') 4 | 5 | import { EventEmitter } from '@better-scroll/shared-utils' 6 | 7 | const ScrollerActions = jest 8 | .fn() 9 | .mockImplementation( 10 | ( 11 | scrollBehaviorX, 12 | scrollBehaviorY, 13 | actionsHandler, 14 | animater, 15 | bscrollOptions 16 | ) => { 17 | const directionLockAction = new DirectionLock(0, false, '') 18 | 19 | return { 20 | options: bscrollOptions, 21 | scrollBehaviorX, 22 | scrollBehaviorY, 23 | actionsHandler, 24 | animater, 25 | directionLockAction, 26 | moved: false, 27 | enabled: true, 28 | startTime: 0, 29 | endTime: 0, 30 | ensuringInteger: false, 31 | getCurrentPos: jest.fn().mockImplementation(() => { 32 | return { 33 | x: 0, 34 | y: 0, 35 | } 36 | }), 37 | refresh: jest.fn(), 38 | destroy: jest.fn(), 39 | hooks: new EventEmitter([ 40 | 'start', 41 | 'beforeMove', 42 | 'scrollStart', 43 | 'scroll', 44 | 'beforeEnd', 45 | 'end', 46 | 'scrollEnd', 47 | 'contentNotMoved', 48 | 'detectMovingDirection', 49 | ]), 50 | } 51 | } 52 | ) 53 | 54 | export default ScrollerActions 55 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__mocks__/Options.ts: -------------------------------------------------------------------------------- 1 | const mockOptions = jest.fn().mockImplementation(() => { 2 | return { 3 | startX: 0, 4 | startY: 0, 5 | scrollX: false, 6 | scrollY: true, 7 | freeScroll: false, 8 | directionLockThreshold: 0, 9 | eventPassthrough: '', 10 | click: false, 11 | tap: '', 12 | translateZ: ' translateZ(0)', 13 | 14 | bounce: { 15 | top: true, 16 | bottom: true, 17 | left: true, 18 | right: true, 19 | }, 20 | bounceTime: 800, 21 | 22 | momentum: true, 23 | momentumLimitTime: 300, 24 | momentumLimitDistance: 15, 25 | 26 | swipeTime: 2500, 27 | swipeBounceTime: 500, 28 | 29 | deceleration: 0.0015, 30 | 31 | flickLimitTime: 200, 32 | flickLimitDistance: 100, 33 | 34 | resizePolling: 60, 35 | probeType: 0, 36 | 37 | stopPropagation: false, 38 | preventDefault: true, 39 | preventDefaultException: { 40 | tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/, 41 | }, 42 | 43 | HWCompositing: true, 44 | 45 | useTransition: true, 46 | bindToWrapper: false, 47 | disableMouse: true, 48 | observeDOM: true, 49 | autoBlur: true, 50 | mouseWheel: false, 51 | infinity: false, 52 | specifiedIndexAsContent: 0, 53 | quadrant: 0, 54 | outOfBoundaryDampingFactor: 1 / 3, 55 | merge: jest.fn(), 56 | process: jest.fn(), 57 | } 58 | }) 59 | 60 | export { mockOptions as OptionsConstructor } 61 | -------------------------------------------------------------------------------- /plugins/request/request.js: -------------------------------------------------------------------------------- 1 | import Config from '@/assets/js/config.js' 2 | const { TIMEOUT } = Config 3 | 4 | 5 | //request封装 6 | function request (type = 'GET', url, options) { 7 | return new Promise((resolve,reject) => { 8 | uni.request({ 9 | url: url, 10 | data: options.params || {}, 11 | method: type || 'GET', 12 | header: options.headers || {}, 13 | responseType: options.responseType || 'text', 14 | timeout: TIMEOUT, 15 | sslVerify: false, 16 | success: ((res) => { 17 | resolve(res) 18 | }), 19 | fail:((err)=>{ 20 | plus.nativeUI.toast("网络错误!", {verticalAlign: 'bottom'}); 21 | reject(err); 22 | }) 23 | }) 24 | }) 25 | } 26 | 27 | export default class http { 28 | get(url, options = {}) { 29 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径 30 | return request('GET', url, options) 31 | } 32 | postget(url, options = {}) { 33 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径 34 | return request('POST', url, options) 35 | } 36 | post(url, options = {}) { 37 | return request('POST', url, options) 38 | } 39 | } 40 | 41 | function param(data, charset) { 42 | let url = '' 43 | for (var k in data) { 44 | let value = data[k] !== undefined ? data[k] : '' 45 | url += charset == 'utf-8' ? `&${k}=${encodeURIComponent(value)}` : `&${k}=${value}` 46 | } 47 | return url ? url.substring(1) : '' 48 | } -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/createOptions.ts: -------------------------------------------------------------------------------- 1 | import { Options as BScrollOptions } from '../Options' 2 | import { Options as ActionsHandlerOptions } from '../base/ActionsHandler' 3 | import { Options as BehaviorOptions, Bounces, Rect } from './Behavior' 4 | 5 | export function createActionsHandlerOptions(bsOptions: BScrollOptions) { 6 | const options = [ 7 | 'click', 8 | 'bindToWrapper', 9 | 'disableMouse', 10 | 'disableTouch', 11 | 'preventDefault', 12 | 'stopPropagation', 13 | 'tagException', 14 | 'preventDefaultException', 15 | 'autoEndDistance', 16 | ].reduce((prev, cur) => { 17 | prev[cur] = bsOptions[cur] 18 | return prev 19 | }, {} as ActionsHandlerOptions) 20 | return options 21 | } 22 | 23 | export function createBehaviorOptions( 24 | bsOptions: BScrollOptions, 25 | extraProp: 'scrollX' | 'scrollY', 26 | bounces: Bounces, 27 | rect: Rect 28 | ) { 29 | const options = [ 30 | 'momentum', 31 | 'momentumLimitTime', 32 | 'momentumLimitDistance', 33 | 'deceleration', 34 | 'swipeBounceTime', 35 | 'swipeTime', 36 | 'outOfBoundaryDampingFactor', 37 | 'specifiedIndexAsContent', 38 | ].reduce((prev, cur) => { 39 | prev[cur] = bsOptions[cur] 40 | return prev 41 | }, {} as BehaviorOptions) 42 | // add extra property 43 | options.scrollable = !!bsOptions[extraProp] 44 | options.bounces = bounces 45 | options.rect = rect 46 | return options 47 | } 48 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__tests__/createOptions.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createActionsHandlerOptions, 3 | createBehaviorOptions, 4 | } from '../createOptions' 5 | import { OptionsConstructor } from '../../Options' 6 | 7 | jest.mock('../../Options') 8 | 9 | describe('createOptions helper function tests', () => { 10 | let bsOptions: any 11 | beforeEach(() => { 12 | bsOptions = new OptionsConstructor() 13 | }) 14 | it('should return correct object when invoking createActionsHandlerOptions function', () => { 15 | let ret = createActionsHandlerOptions(bsOptions) 16 | 17 | expect(ret).toEqual({ 18 | click: false, 19 | bindToWrapper: false, 20 | disableMouse: true, 21 | preventDefault: true, 22 | stopPropagation: false, 23 | preventDefaultException: { 24 | tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|AUDIO)$/, 25 | }, 26 | }) 27 | }) 28 | 29 | it('should return correct object when invoking createBehaviorOptions function', () => { 30 | let ret = createBehaviorOptions(bsOptions, 'scrollY', [true, true], { 31 | size: 'width', 32 | position: 'top', 33 | }) 34 | 35 | expect(ret).toEqual({ 36 | momentum: true, 37 | momentumLimitTime: 300, 38 | momentumLimitDistance: 15, 39 | deceleration: 0.0015, 40 | swipeBounceTime: 500, 41 | swipeTime: 2500, 42 | scrollable: true, 43 | outOfBoundaryDampingFactor: 1 / 3, 44 | specifiedIndexAsContent: 0, 45 | bounces: [true, true], 46 | rect: { 47 | size: 'width', 48 | position: 'top', 49 | }, 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /components/music-lyric/music-lyric.nvue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 59 | 60 | 62 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Behavior.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils' 2 | 3 | const Behavior = jest.fn().mockImplementation((content, bscrollOptions) => { 4 | return { 5 | content, 6 | options: bscrollOptions, 7 | startPos: 0, 8 | currentPos: 0, 9 | absStartPos: 0, 10 | dist: 0, 11 | minScrollPos: 0, 12 | maxScrollPos: 0, 13 | hasScroll: true, 14 | direction: 0, 15 | movingDirection: 0, 16 | relativeOffset: 0, 17 | wrapperSize: 0, 18 | contentSize: 0, 19 | hooks: new EventEmitter([ 20 | 'momentum', 21 | 'end', 22 | 'beforeComputeBoundary', 23 | 'computeBoundary', 24 | 'ignoreHasScroll', 25 | ]), 26 | start: jest.fn(), 27 | move: jest.fn(), 28 | end: jest.fn(), 29 | updateDirection: jest.fn(), 30 | refresh: jest.fn(), 31 | updatePosition: jest.fn(), 32 | getCurrentPos: jest.fn().mockImplementation(() => { 33 | return 0 34 | }), 35 | checkInBoundary: jest.fn().mockImplementation(() => { 36 | return { 37 | position: 0, 38 | inBoundary: false, 39 | } 40 | }), 41 | adjustPosition: jest.fn(), 42 | updateStartPos: jest.fn(), 43 | updateAbsStartPos: jest.fn(), 44 | resetStartPos: jest.fn(), 45 | getAbsDist: jest.fn().mockImplementation((delta: number) => { 46 | return Math.abs(delta) 47 | }), 48 | destroy: jest.fn(), 49 | computeBoundary: jest.fn(), 50 | setMovingDirection: jest.fn(), 51 | setDirection: jest.fn(), 52 | performDampingAlgorithm: jest.fn(), 53 | } 54 | }) 55 | 56 | export { Behavior } 57 | -------------------------------------------------------------------------------- /android/com/itstudy/io/GetDirectoryList.java: -------------------------------------------------------------------------------- 1 | package com.itstudy.io; 2 | 3 | 4 | import org.json.JSONArray; 5 | import org.json.JSONException; 6 | import org.json.JSONObject; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.text.SimpleDateFormat; 11 | 12 | /** 13 | * @Title: FileList 14 | * @author: 康雷 e-mail: 1014295211@qq.com 15 | * @date: 2020/9/22 16:51 16 | * @ClassName: GetDirectoryList 17 | * @Description: 获取指定路径下的文件夹列表 18 | */ 19 | public class GetDirectoryList { 20 | 21 | 22 | public String getDirectories(String path) throws IOException, JSONException { 23 | File file = new File(path); 24 | File[] files = file.listFiles(); 25 | JSONArray folderJsonArray = new JSONArray(); 26 | for (File value : files) { 27 | if ( !value.isHidden() ) { 28 | JSONObject jsonObject = new JSONObject(); 29 | if (value.isDirectory()) { 30 | jsonObject.put("name", value.getName()); 31 | jsonObject.put("path", value.getPath()); 32 | jsonObject.put("type", "folder"); 33 | jsonObject.put("size", "0B"); 34 | jsonObject.put("time", this.getFileTime(value)); 35 | jsonObject.put("createTime",value.lastModified()); 36 | folderJsonArray.put(jsonObject); 37 | } 38 | } 39 | } 40 | return folderJsonArray.toString(); 41 | } 42 | 43 | private String getFileTime(File file) { 44 | SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 45 | return formatter.format(file.lastModified()); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /common/mixin/lyric.js: -------------------------------------------------------------------------------- 1 | import musicMixin from '@/common/mixin/music.js' 2 | import musiccertifyMixin from '@/common/mixin/musiccertify.js' 3 | const lyricMixin = { 4 | mixins: [musicMixin, musiccertifyMixin], 5 | computed: { 6 | //播放记录 7 | playRecord () { 8 | return this.getMusicPlayRecord; 9 | }, 10 | //已播放时长 11 | playTime () { 12 | return this.getMusicPlayTime; 13 | }, 14 | playLyric () { 15 | return this.getMusicLyric; 16 | }, 17 | //是否显示歌词 18 | lyricShow () { 19 | return this.getMusicLyricShow; 20 | }, 21 | //当前歌词字符串 22 | lyricNowTitle () { 23 | return this.playLyric.length > 0 && this.lyricNowIndex > -1 ? this.playLyric[this.lyricNowIndex].title : this.musicInfo ? this.musicInfo.name : '暂无歌曲'; 24 | }, 25 | //当前歌词位置索引 26 | lyricNowIndex () { 27 | let len = this.playLyric.length; 28 | let nowLyricTime = 0; 29 | let prevLyricTime = 0; 30 | let nextLyricTime = 0; 31 | for ( let i = 0; i < len; i++ ) { 32 | nowLyricTime = this.playLyric[i].time; 33 | switch(i) { 34 | case 0: 35 | nextLyricTime = this.playLyric[i + 1].time; 36 | if ( this.playTime < nextLyricTime && this.playTime >= nowLyricTime ) return i; 37 | break; 38 | case this.playLyric.length - 1: 39 | prevLyricTime = this.playLyric[i - 1].time; 40 | if ( this.playTime > prevLyricTime && this.playTime >= nowLyricTime ) return i; 41 | break; 42 | default: 43 | prevLyricTime = this.playLyric[i - 1].time; 44 | nextLyricTime = this.playLyric[i + 1].time; 45 | if ( this.playTime > prevLyricTime && this.playTime < nextLyricTime && this.playTime >= nowLyricTime ) return i; 46 | } 47 | } 48 | return -1; 49 | } 50 | } 51 | } 52 | export default lyricMixin; -------------------------------------------------------------------------------- /common/mixin/index.js: -------------------------------------------------------------------------------- 1 | import { mapGetters, mapMutations } from 'vuex' 2 | export const skinMixin = { 3 | computed: { 4 | ...mapGetters({ 5 | skinMode: 'skin/skinMode', 6 | skinColor: 'skin/skinColor' 7 | }) 8 | }, 9 | methods: { 10 | ...mapMutations({ 11 | changeSkin: 'skin/changeSkin', 12 | }) 13 | } 14 | } 15 | 16 | //菜单拖曳显示 17 | export const menuTouchMixin = { 18 | data () { 19 | return { 20 | pointX: 0, 21 | touchTime: 0, 22 | menuLate: 0, 23 | menuOpac: 0, 24 | //控制列表是否滚动 25 | scrollable: true 26 | } 27 | }, 28 | methods: { 29 | touchstart (e) { 30 | if ( e.touches.length > 1 ) { 31 | return; 32 | } 33 | const touch = e.touches[0]; 34 | this.pointX = touch.pageX; 35 | this.scrollable = false; 36 | this.$refs.leftMenu.open(); 37 | this.timer = setInterval(() => { 38 | this.touchTime += 0.1; 39 | }, 100) 40 | }, 41 | touchmove (e) { 42 | if ( this.touchTime < 0.3 ) { 43 | return; 44 | } 45 | const touch = e.touches[0]; 46 | this.menuLate = this.$refs.leftMenu.mulriple * (touch.pageX - this.pointX); 47 | this.menuOpac = this.menuLate / Math.abs(this.$refs.leftMenu.anima.late) * this.$refs.leftMenu.anima.opac; 48 | }, 49 | touchend (e) { 50 | if ( this.timer ) { 51 | clearInterval(this.timer); 52 | } 53 | if ( this.$refs.leftMenu.popuplate >= -240 || (this.touchTime <= 0.3 && this.$refs.leftMenu.popuplate > -540) ) { 54 | this.$refs.leftMenu.show(); 55 | } else { 56 | this.$refs.leftMenu.hide(); 57 | setTimeout(() => { 58 | this.menuLate = -30; 59 | }, this.$refs.leftMenu.anima.duration) 60 | } 61 | this.$nextTick(() => { 62 | this.pointX = 0; 63 | this.touchTime = 0; 64 | this.scrollable = true; 65 | }) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /store/modules/skin.js: -------------------------------------------------------------------------------- 1 | import { SKIN } from '../config.js' 2 | 3 | const state = { 4 | skin: uni.getStorageSync(SKIN) || 'default' //皮肤 5 | } 6 | 7 | const getters = { 8 | //当前皮肤模式 9 | skinMode (state) { 10 | return state.skin 11 | }, 12 | skinColor (state) { 13 | // 默认皮肤 14 | if ( state.skin == 'default' ) { 15 | return { 16 | bgColor: '#FAFAFA', 17 | titleColor: '#333333', 18 | textColor: '#666666', 19 | itemColor: '#1776D3', 20 | navColor: '#2196F5', 21 | iconColor: '#FFFFFF', 22 | gapColor: '#E0E0E0', 23 | menuBgColor: '#FAFAFA', 24 | menuIconColor: '#737373', 25 | menuTitleColor: '#727272', 26 | menuActiveColor: '#2397EE', 27 | menuActiveBgColor: '#DDDDDD', 28 | imgMask: 0, 29 | readBackColor: '#BFAD8A', 30 | readTextColor: '#2E2B23', 31 | activeBgColor: '#2397EE', 32 | activeColor: '#FAFAFA', 33 | activedName: 'actived' 34 | } 35 | } else if ( state.skin == 'night' ) {// 夜间模式 36 | return { 37 | bgColor: '#2C2C2C', 38 | titleColor: '#8F8F8F', 39 | textColor: '#5E5E5E', 40 | itemColor: '#3D3D3D', 41 | navColor: '#3C3C3C', 42 | iconColor: '#777777', 43 | gapColor: '#3F3F3F', 44 | menuBgColor: '#373737', 45 | menuIconColor: '#777777', 46 | menuTitleColor: '#8F8F8F', 47 | menuActiveColor: '#FAFAFA', 48 | menuActiveBgColor: '#3F3F3F', 49 | imgMask: 0.3, 50 | readBackColor: '#393E41', 51 | readTextColor: '#95A3A6', 52 | activeBgColor: '#3F3F3F', 53 | activeColor: '#777777', 54 | activedName: 'actived-dark' 55 | } 56 | } 57 | } 58 | } 59 | 60 | const mutations = { 61 | //改变皮肤模式 62 | changeSkin (state, skin) { 63 | state.skin = skin; 64 | uni.setStorageSync(SKIN, skin) 65 | } 66 | } 67 | 68 | export default { 69 | namespaced: true, 70 | state, 71 | getters, 72 | mutations 73 | } -------------------------------------------------------------------------------- /plugins/dom/index.js: -------------------------------------------------------------------------------- 1 | export default { 2 | //选择对话框 3 | actionSheet (list, current = -1) { 4 | return new Promise((resolve, reject) => { 5 | uni.navigateTo({ 6 | url: `/modules/actionSheet?list=${encodeURIComponent(JSON.stringify(list))}¤t=${current}`, 7 | complete: (res) => { 8 | setTimeout(() => { 9 | uni.$on('actionSheet-btn', (data) => { 10 | resolve(data) 11 | uni.navigateBack({delta: 1}) 12 | uni.$off('actionSheet-btn'); 13 | }) 14 | }, 60) 15 | } 16 | }); 17 | }) 18 | }, 19 | //确认对话框 20 | confirm (title = '', message = '') { 21 | return new Promise((resolve, reject) => { 22 | uni.navigateTo({ 23 | url: `/modules/confirm?title=${title}&message=${encodeURIComponent(message)}`, 24 | complete: (res) => { 25 | setTimeout(() => { 26 | uni.$on('message-btn', (data) => { 27 | resolve(data.flag) 28 | uni.navigateBack({delta: 1}) 29 | uni.$off('message-btn'); 30 | }) 31 | }, 60) 32 | } 33 | }); 34 | }) 35 | }, 36 | catalog (type) { 37 | return new Promise((resolve, reject) => { 38 | uni.navigateTo({ 39 | url: `/modules/catalog?type=${type}`, 40 | complete: (res) => { 41 | uni.$on('catalog-btn', (data) => { 42 | resolve(data) 43 | uni.navigateBack({delta: 1}); 44 | uni.$off('catalog-btn'); 45 | }) 46 | } 47 | }); 48 | }) 49 | }, 50 | security (data = {}) { 51 | const type = data.type || 'input' 52 | const title = data.title || '请输入安全密码' 53 | return new Promise((resolve, reject) => { 54 | uni.navigateTo({ 55 | url: `/modules/security?type=${type}&title=${title}`, 56 | complete: (res) => { 57 | uni.$on('security-btn', (data) => { 58 | resolve(data) 59 | uni.navigateBack({delta: 1}); 60 | uni.$off('security-btn'); 61 | }) 62 | } 63 | }); 64 | }) 65 | } 66 | } -------------------------------------------------------------------------------- /plugins/xhr/xhr.js: -------------------------------------------------------------------------------- 1 | import Config from '@/assets/js/config.js' 2 | const { TIMEOUT } = Config 3 | 4 | //xhr封装 5 | function xhrRequest (type = 'GET', url, options) { 6 | let xhrHttp = new plus.net.XMLHttpRequest(); 7 | return new Promise((resolve,reject) => { 8 | xhrHttp.onreadystatechange = function () { 9 | console.log(xhrHttp.readyState); 10 | if ( xhrHttp.readyState == 4 ) { 11 | if ( xhrHttp.status == 200 ) { 12 | resolve({code: xhrHttp.status, data: xhrHttp.responseText}) 13 | } else { 14 | plus.nativeUI.toast("网络错误!", {verticalAlign: 'bottom'}); 15 | reject({code: xhrHttp.status, data: ''}); 16 | } 17 | } 18 | } 19 | xhrHttp.open(type, url); 20 | if ( options.mimeType ) { 21 | xhrHttp.overrideMimeType(options.mimeType); 22 | } 23 | xhrHttp.responseType = options.responseType || 'json'; 24 | for ( let i in options.headers || {} ) { 25 | xhrHttp.setRequestHeader(i, options.headers[i]); 26 | } 27 | xhrHttp.timeout = TIMEOUT; 28 | xhrHttp.send(options.params || {}); 29 | }) 30 | } 31 | 32 | export default class Xhr { 33 | get(url, options = {}) { 34 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径 35 | return xhrRequest('GET', url, options) 36 | } 37 | postget(url, options = {}) { 38 | url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''; // 请求路径 39 | return xhrRequest('POST', url, options) 40 | } 41 | post(url, options = {}) { 42 | return xhrRequest('POST', url, options) 43 | } 44 | } 45 | 46 | function param(data, charset) { 47 | let url = '' 48 | for (var k in data) { 49 | let value = data[k] !== undefined ? data[k] : '' 50 | url += charset == 'utf-8' ? `&${k}=${encodeURIComponent(value)}` : `&${k}=${value}` 51 | } 52 | return url ? url.substring(1) : '' 53 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "haoyong-reader", 3 | "displayName": "小说和漫画阅读器(好用阅读器)", 4 | "version": "2.9.8.5", 5 | "description": "能阅读小说和漫画, 还能播放音乐的阅读器", 6 | "keywords": [ 7 | "小说", 8 | "漫画", 9 | "阅读", 10 | "翻页", 11 | "音乐" 12 | ], 13 | "repository": "https://github.com/yingbing-developer/uni-reader.git", 14 | "engines": { 15 | "HBuilderX": "^3.1.0" 16 | }, 17 | "dcloudext": { 18 | "category": [ 19 | "前端页面模板", 20 | "uni-app前端项目模板" 21 | ], 22 | "sale": { 23 | "regular": { 24 | "price": "0.00" 25 | }, 26 | "sourcecode": { 27 | "price": "0.00" 28 | } 29 | }, 30 | "contact": { 31 | "qq": "1014295211" 32 | }, 33 | "declaration": { 34 | "ads": "无", 35 | "data": "无", 36 | "permissions": "系统存储权限" 37 | }, 38 | "npmurl": "" 39 | }, 40 | "uni_modules": { 41 | "dependencies": [], 42 | "encrypt": [], 43 | "platforms": { 44 | "cloud": { 45 | "tcb": "y", 46 | "aliyun": "y" 47 | }, 48 | "client": { 49 | "App": { 50 | "app-vue": "y", 51 | "app-nvue": "y" 52 | }, 53 | "H5-mobile": { 54 | "Safari": "n", 55 | "Android Browser": "n", 56 | "微信浏览器(Android)": "n", 57 | "QQ浏览器(Android)": "n" 58 | }, 59 | "H5-pc": { 60 | "Chrome": "n", 61 | "IE": "n", 62 | "Edge": "n", 63 | "Firefox": "n", 64 | "Safari": "n" 65 | }, 66 | "小程序": { 67 | "微信": "n", 68 | "阿里": "n", 69 | "百度": "n", 70 | "字节跳动": "n", 71 | "QQ": "n" 72 | }, 73 | "快应用": { 74 | "华为": "n", 75 | "联盟": "n" 76 | }, 77 | "Vue": { 78 | "vue2": "y", 79 | "vue3": "n" 80 | } 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /components/fixed-button/fixed-button.nvue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 70 | 71 | 84 | -------------------------------------------------------------------------------- /App.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 87 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import Translater from '../index' 2 | 3 | describe('Translater Class test suit', () => { 4 | let translater: Translater 5 | let contentEl = document.createElement('div') 6 | 7 | beforeEach(() => { 8 | translater = new Translater(contentEl) 9 | }) 10 | afterEach(() => { 11 | jest.clearAllMocks() 12 | }) 13 | 14 | it('work well when call translate()', () => { 15 | const mockFn1 = jest.fn() 16 | const mockFn2 = jest.fn() 17 | translater.hooks.on(translater.hooks.eventTypes.beforeTranslate, mockFn1) 18 | translater.hooks.on(translater.hooks.eventTypes.translate, mockFn2) 19 | 20 | translater.translate({ x: 0, y: 0, dummy: 0 }) 21 | 22 | expect(mockFn1).toBeCalled() 23 | expect(mockFn1).toBeCalledWith(['translateX(0px)', 'translateY(0px)'], { 24 | x: 0, 25 | y: 0, 26 | dummy: 0, 27 | }) 28 | expect(mockFn2).toBeCalled() 29 | expect(mockFn2).toBeCalledWith({ x: 0, y: 0, dummy: 0 }) 30 | expect(translater.content.style.transform).toBe( 31 | 'translateX(0px) translateY(0px)' 32 | ) 33 | }) 34 | 35 | it('get correct position when call getComputedPosition()', () => { 36 | // jsDOM library's getComputedStyle is different from browser 37 | window.getComputedStyle = jest.fn().mockImplementation(() => { 38 | return { 39 | transform: 'matrix(1, 0, 0, 1, 0, 0)', 40 | } 41 | }) 42 | const { x, y } = translater.getComputedPosition() 43 | 44 | expect(x).toBe(0) 45 | expect(y).toBe(0) 46 | }) 47 | 48 | it('should clear hooks when destroyed', () => { 49 | translater.hooks.on(translater.hooks.eventTypes.beforeTranslate, () => {}) 50 | 51 | expect(translater.hooks.eventTypes.beforeTranslate).toBe('beforeTranslate') 52 | 53 | translater.destroy() 54 | 55 | expect(translater.hooks.eventTypes.beforeTranslate).toBeFalsy() 56 | }) 57 | }) 58 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__mocks__/index.ts: -------------------------------------------------------------------------------- 1 | import Scroller from '../scroller/Scroller' 2 | import { OptionsConstructor } from '../Options' 3 | import { EventEmitter } from '@better-scroll/shared-utils' 4 | 5 | jest.mock('../scroller/Scroller') 6 | jest.mock('../Options') 7 | 8 | const BScroll = jest.fn().mockImplementation((wrapper, options) => { 9 | options = Object.assign(new OptionsConstructor(), options) 10 | const eventEmitter = new EventEmitter([ 11 | // bscroll 12 | 'refresh', 13 | 'enable', 14 | 'disable', 15 | 'destroy', 16 | // scroller 17 | 'beforeScrollStart', 18 | 'scrollStart', 19 | 'scroll', 20 | 'scrollEnd', 21 | 'touchEnd', 22 | 'flick', 23 | 'alterOptions', 24 | 'mousewheelStart', 25 | 'mousewheelMove', 26 | 'mousewheelEnd', 27 | ]) 28 | const res = { 29 | wrapper: wrapper, 30 | options: options, 31 | hooks: new EventEmitter([ 32 | 'refresh', 33 | 'enable', 34 | 'disable', 35 | 'destroy', 36 | 'beforeInitialScrollTo', 37 | ]), 38 | scroller: new Scroller(wrapper, wrapper.children[0], options), 39 | // own methods 40 | proxy: jest.fn(), 41 | refresh: jest.fn(), 42 | // proxy methods 43 | scrollTo: jest.fn(), 44 | resetPosition: jest.fn(), 45 | registerType: jest.fn().mockImplementation((names: string[]) => { 46 | names.forEach((name) => { 47 | const eventTypes = eventEmitter.eventTypes 48 | eventTypes[name] = name 49 | }) 50 | }), 51 | disable: jest.fn(), 52 | enable: jest.fn(), 53 | stop: jest.fn(), 54 | plugins: {}, 55 | x: 0, 56 | y: 0, 57 | maxScrollY: 0, 58 | maxScrollX: 0, 59 | minScrollX: 0, 60 | minScrollY: 0, 61 | hasVerticalScroll: true, 62 | hasHorizontalScroll: false, 63 | enabled: true, 64 | pending: false, 65 | } 66 | 67 | Object.setPrototypeOf(res, eventEmitter) 68 | return res 69 | }) 70 | 71 | export default BScroll 72 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/dist/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import BScroll from '@better-scroll/core'; 2 | export declare type PullDownRefreshOptions = Partial | true; 3 | declare const enum PullDownPhase { 4 | DEFAULT = 0, 5 | MOVING = 1, 6 | FETCHING = 2 7 | } 8 | declare const enum ThresholdBoundary { 9 | DEFAULT = 0, 10 | INSIDE = 1, 11 | OUTSIDE = 2 12 | } 13 | export interface PullDownRefreshConfig { 14 | threshold: number; 15 | stop: number; 16 | } 17 | declare module '@better-scroll/core' { 18 | interface CustomOptions { 19 | pullDownRefresh?: PullDownRefreshOptions; 20 | } 21 | interface CustomAPI { 22 | pullDownRefresh: PluginAPI; 23 | } 24 | } 25 | interface PluginAPI { 26 | finishPullDown(): void; 27 | openPullDown(config?: PullDownRefreshOptions): void; 28 | closePullDown(): void; 29 | autoPullDownRefresh(): void; 30 | } 31 | export default class PullDown implements PluginAPI { 32 | scroll: BScroll; 33 | static pluginName: string; 34 | private hooksFn; 35 | pulling: PullDownPhase; 36 | thresholdBoundary: ThresholdBoundary; 37 | watching: boolean; 38 | options: PullDownRefreshConfig; 39 | cachedOriginanMinScrollY: number; 40 | currentMinScrollY: number; 41 | constructor(scroll: BScroll); 42 | private setPulling; 43 | private setThresholdBoundary; 44 | private init; 45 | private handleBScroll; 46 | private handleOptions; 47 | private handleHooks; 48 | private registerHooks; 49 | private hasMouseWheelPlugin; 50 | private watch; 51 | private resetStateBeforeScrollStart; 52 | private checkLocationOfThresholdBoundary; 53 | private locateInsideThresholdBoundary; 54 | private unwatch; 55 | private checkPullDown; 56 | private isFetchingStatus; 57 | private modifyBehaviorYBoundary; 58 | finishPullDown(): void; 59 | openPullDown(config?: PullDownRefreshOptions): void; 60 | closePullDown(): void; 61 | autoPullDownRefresh(): void; 62 | } 63 | export {}; 64 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "yingbing-ReadPage", 3 | "displayName": "小说阅读分页插件", 4 | "version": "1.2.4", 5 | "description": "给小说分页的插件,包含翻页", 6 | "keywords": [ 7 | "小说", 8 | "阅读", 9 | "翻页", 10 | "分页" 11 | ], 12 | "repository": "https://github.com/yingbing-developer/uni-readPage.git", 13 | "engines": { 14 | "HBuilderX": "^3.1.0" 15 | }, 16 | "dcloudext": { 17 | "category": [ 18 | "前端组件", 19 | "通用组件" 20 | ], 21 | "sale": { 22 | "regular": { 23 | "price": "0.00" 24 | }, 25 | "sourcecode": { 26 | "price": "0.00" 27 | } 28 | }, 29 | "contact": { 30 | "qq": "1014295211" 31 | }, 32 | "declaration": { 33 | "ads": "无", 34 | "data": "无", 35 | "permissions": "无" 36 | }, 37 | "npmurl": "" 38 | }, 39 | "uni_modules": { 40 | "dependencies": [], 41 | "encrypt": [], 42 | "platforms": { 43 | "cloud": { 44 | "tcb": "y", 45 | "aliyun": "y" 46 | }, 47 | "client": { 48 | "App": { 49 | "app-vue": "y", 50 | "app-nvue": "n" 51 | }, 52 | "H5-mobile": { 53 | "Safari": "u", 54 | "Android Browser": "y", 55 | "微信浏览器(Android)": "y", 56 | "QQ浏览器(Android)": "y" 57 | }, 58 | "H5-pc": { 59 | "Chrome": "n", 60 | "IE": "n", 61 | "Edge": "n", 62 | "Firefox": "n", 63 | "Safari": "n" 64 | }, 65 | "小程序": { 66 | "微信": "n", 67 | "阿里": "n", 68 | "百度": "n", 69 | "字节跳动": "n", 70 | "QQ": "n" 71 | }, 72 | "快应用": { 73 | "华为": "u", 74 | "联盟": "u" 75 | }, 76 | "Vue": { 77 | "vue2": "y", 78 | "vue3": "u" 79 | } 80 | } 81 | } 82 | }, 83 | "dependencies": { 84 | "@better-scroll/core": "^2.4.2", 85 | "@better-scroll/infinity": "^2.4.2", 86 | "@better-scroll/pull-down": "^2.4.2", 87 | "@better-scroll/pull-up": "^2.4.2" 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "@better-scroll/pull-up", 3 | "_id": "@better-scroll/pull-up@2.4.2", 4 | "_inBundle": false, 5 | "_integrity": "sha512-07Cke3oa96lN9/inxJZ0ixh0nBbbqxOi2IKcBGtD6dP+susiMcdhgd/c7zNRjXkwlw0vzTNfXTgExIOEWzLHYg==", 6 | "_location": "/@better-scroll/pull-up", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "@better-scroll/pull-up", 12 | "name": "@better-scroll/pull-up", 13 | "escapedName": "@better-scroll%2fpull-up", 14 | "scope": "@better-scroll", 15 | "rawSpec": "", 16 | "saveSpec": null, 17 | "fetchSpec": "latest" 18 | }, 19 | "_requiredBy": [ 20 | "#USER", 21 | "/" 22 | ], 23 | "_resolved": "https://registry.npmjs.org/@better-scroll/pull-up/-/pull-up-2.4.2.tgz", 24 | "_shasum": "25357ceef7bac7520930f0631896b63a10f82a6f", 25 | "_spec": "@better-scroll/pull-up", 26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage", 27 | "author": { 28 | "name": "jizhi", 29 | "email": "theniceangel@163.com" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues" 33 | }, 34 | "bundleDependencies": false, 35 | "dependencies": { 36 | "@better-scroll/core": "^2.4.2" 37 | }, 38 | "deprecated": false, 39 | "description": "pull up to load more data", 40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3", 41 | "homepage": "https://github.com/ustbhuangyi/better-scroll", 42 | "keywords": [ 43 | "scroll", 44 | "iscroll", 45 | "javascript", 46 | "typescript", 47 | "ios", 48 | "pull-up" 49 | ], 50 | "main": "dist/pull-up.min.js", 51 | "module": "dist/pull-up.esm.js", 52 | "name": "@better-scroll/pull-up", 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "repository": { 57 | "type": "git", 58 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git", 59 | "directory": "packages/pull-up" 60 | }, 61 | "typings": "dist/types/index.d.ts", 62 | "version": "2.4.2" 63 | } 64 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "@better-scroll/core", 3 | "_id": "@better-scroll/core@2.4.2", 4 | "_inBundle": false, 5 | "_integrity": "sha512-IqVZLnh04YpaEAy9wJDxtFK/stxVQjB9A9Wcr3Uwkj7Av1TtFpin+t/TObl53diNDG5ZJ+vck/OAthphpuugLA==", 6 | "_location": "/@better-scroll/core", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "@better-scroll/core", 12 | "name": "@better-scroll/core", 13 | "escapedName": "@better-scroll%2fcore", 14 | "scope": "@better-scroll", 15 | "rawSpec": "", 16 | "saveSpec": null, 17 | "fetchSpec": "latest" 18 | }, 19 | "_requiredBy": [ 20 | "#USER", 21 | "/" 22 | ], 23 | "_resolved": "https://registry.npmjs.org/@better-scroll/core/-/core-2.4.2.tgz", 24 | "_shasum": "e69470012d79923a18034c3e4931720fbb06eae5", 25 | "_spec": "@better-scroll/core", 26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage", 27 | "author": { 28 | "name": "jizhi", 29 | "email": "theniceangel@163.com" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues" 33 | }, 34 | "bundleDependencies": false, 35 | "dependencies": { 36 | "@better-scroll/shared-utils": "^2.4.2" 37 | }, 38 | "deprecated": false, 39 | "description": "Minimalistic core scrolling for BetterScroll, it is pure and tiny", 40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3", 41 | "homepage": "https://github.com/ustbhuangyi/better-scroll", 42 | "keywords": [ 43 | "scroll", 44 | "iscroll", 45 | "javascript", 46 | "typescript", 47 | "ios" 48 | ], 49 | "license": "MIT", 50 | "main": "dist/core.js", 51 | "module": "dist/core.esm.js", 52 | "name": "@better-scroll/core", 53 | "publishConfig": { 54 | "access": "public" 55 | }, 56 | "repository": { 57 | "type": "git", 58 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git", 59 | "directory": "packages/core" 60 | }, 61 | "scripts": {}, 62 | "typings": "dist/types/index.d.ts", 63 | "version": "2.4.2" 64 | } 65 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/Base.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EaseFn, 3 | safeCSSStyleDeclaration, 4 | cancelAnimationFrame, 5 | EventEmitter, 6 | Probe, 7 | } from '@better-scroll/shared-utils' 8 | import Translater, { TranslaterPoint } from '../translater' 9 | 10 | export interface ExposedAPI { 11 | stop(): void 12 | } 13 | 14 | export default abstract class Base implements ExposedAPI { 15 | content: HTMLElement 16 | style: safeCSSStyleDeclaration 17 | hooks: EventEmitter 18 | timer: number = 0 19 | pending: boolean 20 | callStopWhenPending: boolean 21 | forceStopped: boolean 22 | _reflow: number; 23 | [key: string]: any 24 | 25 | constructor( 26 | content: HTMLElement, 27 | public translater: Translater, 28 | public options: { 29 | probeType: number 30 | } 31 | ) { 32 | this.hooks = new EventEmitter([ 33 | 'move', 34 | 'end', 35 | 'beforeForceStop', 36 | 'forceStop', 37 | 'callStop', 38 | 'time', 39 | 'timeFunction', 40 | ]) 41 | this.setContent(content) 42 | } 43 | 44 | translate(endPoint: TranslaterPoint) { 45 | this.translater.translate(endPoint) 46 | } 47 | 48 | setPending(pending: boolean) { 49 | this.pending = pending 50 | } 51 | 52 | setForceStopped(forceStopped: boolean) { 53 | this.forceStopped = forceStopped 54 | } 55 | 56 | setCallStop(called: boolean) { 57 | this.callStopWhenPending = called 58 | } 59 | 60 | setContent(content: HTMLElement) { 61 | if (this.content !== content) { 62 | this.content = content 63 | this.style = content.style as safeCSSStyleDeclaration 64 | this.stop() 65 | } 66 | } 67 | clearTimer() { 68 | if (this.timer) { 69 | cancelAnimationFrame(this.timer) 70 | this.timer = 0 71 | } 72 | } 73 | 74 | abstract move( 75 | startPoint: TranslaterPoint, 76 | endPoint: TranslaterPoint, 77 | time: number, 78 | easing: string | EaseFn 79 | ): void 80 | 81 | abstract doStop(): void 82 | abstract stop(): void 83 | 84 | destroy() { 85 | this.hooks.destroy() 86 | 87 | cancelAnimationFrame(this.timer) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-down/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "@better-scroll/pull-down", 3 | "_id": "@better-scroll/pull-down@2.4.2", 4 | "_inBundle": false, 5 | "_integrity": "sha512-bqMLk33o4oesTXIIOteBKHQgfVKjIVvity39TM/MfzkbY1WDBxD+HFS7ySgoqw7Kl2Wiv/U76Wfqzmm6yDdg7Q==", 6 | "_location": "/@better-scroll/pull-down", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "tag", 10 | "registry": true, 11 | "raw": "@better-scroll/pull-down", 12 | "name": "@better-scroll/pull-down", 13 | "escapedName": "@better-scroll%2fpull-down", 14 | "scope": "@better-scroll", 15 | "rawSpec": "", 16 | "saveSpec": null, 17 | "fetchSpec": "latest" 18 | }, 19 | "_requiredBy": [ 20 | "#USER", 21 | "/" 22 | ], 23 | "_resolved": "https://registry.npmjs.org/@better-scroll/pull-down/-/pull-down-2.4.2.tgz", 24 | "_shasum": "6b98b28bd73e9b694b0857a9c73879e70339cb96", 25 | "_spec": "@better-scroll/pull-down", 26 | "_where": "G:\\my-project\\uni-readPage\\uni_modules\\yingbing-ReadPage", 27 | "author": { 28 | "name": "jizhi", 29 | "email": "theniceangel@163.com" 30 | }, 31 | "bugs": { 32 | "url": "https://github.com/ustbhuangyi/better-scroll/issues" 33 | }, 34 | "bundleDependencies": false, 35 | "dependencies": { 36 | "@better-scroll/core": "^2.4.2" 37 | }, 38 | "deprecated": false, 39 | "description": "pull down to refresh, behave likes App list refreshing", 40 | "gitHead": "c97e67ecf15e616d998e67aa4ce15a7c429691c3", 41 | "homepage": "https://github.com/ustbhuangyi/better-scroll", 42 | "keywords": [ 43 | "scroll", 44 | "iscroll", 45 | "javascript", 46 | "typescript", 47 | "ios", 48 | "pull-down" 49 | ], 50 | "license": "MIT", 51 | "main": "dist/pull-down.min.js", 52 | "module": "dist/pull-down.esm.js", 53 | "name": "@better-scroll/pull-down", 54 | "publishConfig": { 55 | "access": "public" 56 | }, 57 | "repository": { 58 | "type": "git", 59 | "url": "git+ssh://git@github.com/ustbhuangyi/better-scroll.git", 60 | "directory": "packages/pull-down" 61 | }, 62 | "typings": "dist/types/index.d.ts", 63 | "version": "2.4.2" 64 | } 65 | -------------------------------------------------------------------------------- /pages/about/index.nvue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 48 | 49 | 78 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/translater/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | style, 3 | safeCSSStyleDeclaration, 4 | EventEmitter, 5 | } from '@better-scroll/shared-utils' 6 | export interface TranslaterPoint { 7 | x: number 8 | y: number 9 | [key: string]: number 10 | } 11 | 12 | interface TranslaterMetaData { 13 | x: [string, string] 14 | y: [string, string] 15 | [key: string]: any 16 | } 17 | const translaterMetaData: TranslaterMetaData = { 18 | x: ['translateX', 'px'], 19 | y: ['translateY', 'px'], 20 | } 21 | 22 | export default class Translater { 23 | content: HTMLElement 24 | style: CSSStyleDeclaration 25 | hooks: EventEmitter 26 | constructor(content: HTMLElement) { 27 | this.setContent(content) 28 | this.hooks = new EventEmitter(['beforeTranslate', 'translate']) 29 | } 30 | 31 | getComputedPosition() { 32 | let cssStyle = window.getComputedStyle( 33 | this.content, 34 | null 35 | ) as safeCSSStyleDeclaration 36 | let matrix = cssStyle[style.transform].split(')')[0].split(', ') 37 | const x = +(matrix[12] || matrix[4]) || 0 38 | const y = +(matrix[13] || matrix[5]) || 0 39 | 40 | return { 41 | x, 42 | y, 43 | } 44 | } 45 | 46 | translate(point: TranslaterPoint) { 47 | let transformStyle = [] as string[] 48 | Object.keys(point).forEach((key) => { 49 | if (!translaterMetaData[key]) { 50 | return 51 | } 52 | const transformFnName = translaterMetaData[key][0] 53 | if (transformFnName) { 54 | const transformFnArgUnit = translaterMetaData[key][1] 55 | const transformFnArg = point[key] 56 | transformStyle.push( 57 | `${transformFnName}(${transformFnArg}${transformFnArgUnit})` 58 | ) 59 | } 60 | }) 61 | this.hooks.trigger( 62 | this.hooks.eventTypes.beforeTranslate, 63 | transformStyle, 64 | point 65 | ) 66 | this.style[style.transform as any] = transformStyle.join(' ') 67 | this.hooks.trigger(this.hooks.eventTypes.translate, point) 68 | } 69 | 70 | setContent(content: HTMLElement) { 71 | if (this.content !== content) { 72 | this.content = content 73 | this.style = content.style 74 | } 75 | } 76 | 77 | destroy() { 78 | this.hooks.destroy() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /android/com/itstudy/io/GetExtSDCardPathList.java: -------------------------------------------------------------------------------- 1 | package com.itstudy.io; 2 | 3 | 4 | import android.os.Build; 5 | import android.os.Environment; 6 | import android.os.UserHandle; 7 | import android.support.annotation.RequiresApi; 8 | 9 | import org.json.JSONArray; 10 | import org.json.JSONException; 11 | import org.json.JSONObject; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.lang.reflect.Constructor; 16 | import java.lang.reflect.Method; 17 | 18 | /** 19 | * @Title: FileList 20 | * @author: 康雷 e-mail: 1014295211@qq.com 21 | * @date: 2020/9/22 16:51 22 | * @ClassName: GetExtSDCardPathList 23 | * @Description: 获取扩展TF卡路径 24 | */ 25 | public class GetExtSDCardPathList { 26 | 27 | 28 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 29 | public static String getSDPath() throws IOException, JSONException{ 30 | JSONArray paths = new JSONArray(); 31 | try { 32 | //===========================获取UserEnvironment================ 33 | Class userEnvironment = Class.forName("android.os.Environment$UserEnvironment"); 34 | Method getExternalDirs =userEnvironment.getDeclaredMethod("getExternalDirs"); 35 | getExternalDirs.setAccessible(true); 36 | //========获取构造UserEnvironment的必要参数UserId================ 37 | Class userHandle = Class.forName("android.os.UserHandle"); 38 | Method myUserId = userHandle.getDeclaredMethod("myUserId"); 39 | myUserId.setAccessible(true); 40 | int mUserId = (int) myUserId.invoke(UserHandle.class); 41 | Constructor declaredConstructor = userEnvironment.getDeclaredConstructor(Integer.TYPE); 42 | // 得到UserEnvironment instance 43 | Object instance = declaredConstructor.newInstance(mUserId); 44 | File[] files = (File[]) getExternalDirs.invoke(instance); 45 | for (int i = 0; i < files.length; i++) { 46 | if (Environment.isExternalStorageRemovable(files[i])){ 47 | JSONObject jsonObject = new JSONObject(); 48 | jsonObject.put("path", files[i].getPath()); 49 | paths.put(jsonObject); 50 | } 51 | } 52 | } catch (Exception e) { 53 | 54 | } 55 | return paths.toString(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /components/search/search.nvue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 58 | 59 | 90 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Behavior.d.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from '@better-scroll/shared-utils'; 2 | export declare type Bounces = [boolean, boolean]; 3 | export declare type Rect = { 4 | size: string; 5 | position: string; 6 | }; 7 | export interface Options { 8 | scrollable: boolean; 9 | momentum: boolean; 10 | momentumLimitTime: number; 11 | momentumLimitDistance: number; 12 | deceleration: number; 13 | swipeBounceTime: number; 14 | swipeTime: number; 15 | bounces: Bounces; 16 | rect: Rect; 17 | outOfBoundaryDampingFactor: number; 18 | specifiedIndexAsContent: number; 19 | [key: string]: number | boolean | Bounces | Rect; 20 | } 21 | export declare type Boundary = { 22 | minScrollPos: number; 23 | maxScrollPos: number; 24 | }; 25 | export declare class Behavior { 26 | wrapper: HTMLElement; 27 | options: Options; 28 | content: HTMLElement; 29 | currentPos: number; 30 | startPos: number; 31 | absStartPos: number; 32 | dist: number; 33 | minScrollPos: number; 34 | maxScrollPos: number; 35 | hasScroll: boolean; 36 | direction: number; 37 | movingDirection: number; 38 | relativeOffset: number; 39 | wrapperSize: number; 40 | contentSize: number; 41 | hooks: EventEmitter; 42 | constructor(wrapper: HTMLElement, content: HTMLElement, options: Options); 43 | start(): void; 44 | move(delta: number): number; 45 | setMovingDirection(delta: number): void; 46 | setDirection(delta: number): void; 47 | performDampingAlgorithm(delta: number, dampingFactor: number): number; 48 | end(duration: number): { 49 | destination?: number | undefined; 50 | duration?: number | undefined; 51 | }; 52 | private momentum; 53 | updateDirection(): void; 54 | refresh(content: HTMLElement): void; 55 | private setContent; 56 | private resetState; 57 | computeBoundary(): void; 58 | updatePosition(pos: number): void; 59 | getCurrentPos(): number; 60 | checkInBoundary(): { 61 | position: number; 62 | inBoundary: boolean; 63 | }; 64 | adjustPosition(pos: number): number; 65 | updateStartPos(): void; 66 | updateAbsStartPos(): void; 67 | resetStartPos(): void; 68 | getAbsDist(delta: number): number; 69 | destroy(): void; 70 | } 71 | -------------------------------------------------------------------------------- /components/c-switch/c-switch.nvue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 69 | 70 | 99 | -------------------------------------------------------------------------------- /components/c-button/c-button.nvue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 68 | 69 | 103 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__mocks__/Scroller.ts: -------------------------------------------------------------------------------- 1 | import createAnimater from '../../animater' 2 | import Translater from '../../translater' 3 | import { Behavior } from '../Behavior' 4 | import ActionsHandler from '../../base/ActionsHandler' 5 | import Actions from '../Actions' 6 | 7 | jest.mock('../../animater') 8 | jest.mock('../../translater') 9 | jest.mock('../Behavior') 10 | jest.mock('../../base/ActionsHandler') 11 | jest.mock('../Actions') 12 | 13 | import { EventEmitter, EventRegister } from '@better-scroll/shared-utils' 14 | 15 | const Scroller = jest.fn().mockImplementation((wrapper, bscrollOptions) => { 16 | const content = wrapper.children[0] 17 | const translater = new Translater(content) 18 | const animater = createAnimater(content, translater, bscrollOptions) 19 | const actionsHandler = new ActionsHandler(wrapper, bscrollOptions) 20 | const scrollBehaviorX = new Behavior( 21 | wrapper, 22 | content, 23 | Object.assign(bscrollOptions, { scrollable: bscrollOptions.scrollX }) 24 | ) 25 | const scrollBehaviorY = new Behavior( 26 | wrapper, 27 | content, 28 | Object.assign(bscrollOptions, { scrollable: bscrollOptions.scrollY }) 29 | ) 30 | const actions = new Actions( 31 | scrollBehaviorX, 32 | scrollBehaviorY, 33 | actionsHandler, 34 | animater, 35 | bscrollOptions 36 | ) 37 | return { 38 | wrapper, 39 | content, 40 | options: bscrollOptions, 41 | translater, 42 | animater, 43 | actionsHandler, 44 | actions, 45 | hooks: new EventEmitter([ 46 | 'beforeStart', 47 | 'beforeMove', 48 | 'beforeScrollStart', 49 | 'scrollStart', 50 | 'scroll', 51 | 'beforeEnd', 52 | 'scrollEnd', 53 | 'resize', 54 | 'touchEnd', 55 | 'end', 56 | 'flick', 57 | 'scrollCancel', 58 | 'momentum', 59 | 'scrollTo', 60 | 'minDistanceScroll', 61 | 'scrollToElement', 62 | 'transitionEnd', 63 | 'checkClick', 64 | 'beforeRefresh', 65 | ]), 66 | scrollBehaviorX, 67 | scrollBehaviorY, 68 | resizeRegister: new EventRegister(wrapper, []), 69 | transitionEndRegister: new EventRegister(wrapper, []), 70 | scrollTo: jest.fn(), 71 | resetPosition: jest.fn(), 72 | togglePointerEvents: jest.fn(), 73 | reflow: jest.fn(), 74 | } 75 | }) 76 | 77 | export default Scroller 78 | -------------------------------------------------------------------------------- /components/comic-image/comic-image.nvue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 87 | 88 | 98 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/scroller/Scroller.d.ts: -------------------------------------------------------------------------------- 1 | import ActionsHandler from '../base/ActionsHandler'; 2 | import Translater, { TranslaterPoint } from '../translater'; 3 | import { Animater } from '../animater'; 4 | import { OptionsConstructor as BScrollOptions } from '../Options'; 5 | import { Behavior } from './Behavior'; 6 | import ScrollerActions from './Actions'; 7 | import { EaseItem, EventEmitter, EventRegister } from '@better-scroll/shared-utils'; 8 | export interface ExposedAPI { 9 | scrollTo(x: number, y: number, time?: number, easing?: EaseItem, extraTransform?: { 10 | start: object; 11 | end: object; 12 | }): void; 13 | scrollBy(deltaX: number, deltaY: number, time?: number, easing?: EaseItem): void; 14 | scrollToElement(el: HTMLElement | string, time: number, offsetX: number | boolean, offsetY: number | boolean, easing?: EaseItem): void; 15 | resetPosition(time?: number, easing?: EaseItem): boolean; 16 | } 17 | export default class Scroller implements ExposedAPI { 18 | wrapper: HTMLElement; 19 | content: HTMLElement; 20 | actionsHandler: ActionsHandler; 21 | translater: Translater; 22 | animater: Animater; 23 | scrollBehaviorX: Behavior; 24 | scrollBehaviorY: Behavior; 25 | actions: ScrollerActions; 26 | hooks: EventEmitter; 27 | resizeRegister: EventRegister; 28 | transitionEndRegister: EventRegister; 29 | options: BScrollOptions; 30 | wrapperOffset: { 31 | left: number; 32 | top: number; 33 | }; 34 | _reflow: number; 35 | resizeTimeout: number; 36 | lastClickTime: number | null; 37 | [key: string]: any; 38 | constructor(wrapper: HTMLElement, content: HTMLElement, options: BScrollOptions); 39 | private init; 40 | private registerTransitionEnd; 41 | private bindTranslater; 42 | private bindAnimater; 43 | private bindActions; 44 | private checkFlick; 45 | private momentum; 46 | private checkClick; 47 | private resize; 48 | private transitionEnd; 49 | togglePointerEvents(enabled?: boolean): void; 50 | refresh(content: HTMLElement): void; 51 | private setContent; 52 | scrollBy(deltaX: number, deltaY: number, time?: number, easing?: EaseItem): void; 53 | scrollTo(x: number, y: number, time?: number, easing?: EaseItem, extraTransform?: { 54 | start: {}; 55 | end: {}; 56 | }): void; 57 | scrollToElement(el: HTMLElement | string, time: number, offsetX: number | boolean, offsetY: number | boolean, easing?: EaseItem): void; 58 | resetPosition(time?: number, easing?: EaseItem): boolean; 59 | reflow(): void; 60 | updatePositions(pos: TranslaterPoint): void; 61 | getCurrentPos(): TranslaterPoint; 62 | enable(): void; 63 | disable(): void; 64 | destroy(this: Scroller): void; 65 | } 66 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/DirectionLock.ts: -------------------------------------------------------------------------------- 1 | import { 2 | TouchEvent, 3 | DirectionLock, 4 | EventPassthrough 5 | } from '@better-scroll/shared-utils' 6 | 7 | const enum Passthrough { 8 | Yes = 'yes', 9 | No = 'no' 10 | } 11 | 12 | interface DirectionMap { 13 | [key: string]: { 14 | [key: string]: EventPassthrough 15 | } 16 | } 17 | 18 | const PassthroughHandlers = { 19 | [Passthrough.Yes]: (e: TouchEvent) => { 20 | return true 21 | }, 22 | [Passthrough.No]: (e: TouchEvent) => { 23 | e.preventDefault() 24 | return false 25 | } 26 | } 27 | const DirectionMap: DirectionMap = { 28 | [DirectionLock.Horizontal]: { 29 | [Passthrough.Yes]: EventPassthrough.Horizontal, 30 | [Passthrough.No]: EventPassthrough.Vertical 31 | }, 32 | [DirectionLock.Vertical]: { 33 | [Passthrough.Yes]: EventPassthrough.Vertical, 34 | [Passthrough.No]: EventPassthrough.Horizontal 35 | } 36 | } 37 | 38 | export default class DirectionLockAction { 39 | directionLocked: DirectionLock 40 | constructor( 41 | public directionLockThreshold: number, 42 | public freeScroll: boolean, 43 | public eventPassthrough: string 44 | ) { 45 | this.reset() 46 | } 47 | 48 | reset() { 49 | this.directionLocked = DirectionLock.Default 50 | } 51 | 52 | checkMovingDirection(absDistX: number, absDistY: number, e: TouchEvent) { 53 | this.computeDirectionLock(absDistX, absDistY) 54 | 55 | return this.handleEventPassthrough(e) 56 | } 57 | 58 | adjustDelta(deltaX: number, deltaY: number) { 59 | if (this.directionLocked === DirectionLock.Horizontal) { 60 | deltaY = 0 61 | } else if (this.directionLocked === DirectionLock.Vertical) { 62 | deltaX = 0 63 | } 64 | return { 65 | deltaX, 66 | deltaY 67 | } 68 | } 69 | 70 | private computeDirectionLock(absDistX: number, absDistY: number) { 71 | // If you are scrolling in one direction, lock it 72 | if (this.directionLocked === DirectionLock.Default && !this.freeScroll) { 73 | if (absDistX > absDistY + this.directionLockThreshold) { 74 | this.directionLocked = DirectionLock.Horizontal // lock horizontally 75 | } else if (absDistY >= absDistX + this.directionLockThreshold) { 76 | this.directionLocked = DirectionLock.Vertical // lock vertically 77 | } else { 78 | this.directionLocked = DirectionLock.None // no lock 79 | } 80 | } 81 | } 82 | 83 | private handleEventPassthrough(e: TouchEvent) { 84 | const handleMap = DirectionMap[this.directionLocked] 85 | if (handleMap) { 86 | if (this.eventPassthrough === handleMap[Passthrough.Yes]) { 87 | return PassthroughHandlers[Passthrough.Yes](e) 88 | } else if (this.eventPassthrough === handleMap[Passthrough.No]) { 89 | return PassthroughHandlers[Passthrough.No](e) 90 | } 91 | } 92 | return false 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/scroller/__tests__/DirectionLock.spec.ts: -------------------------------------------------------------------------------- 1 | import DirectionLock from '../DirectionLock' 2 | import { 3 | Direction, 4 | DirectionLock as DirectionLockEnum, 5 | } from '@better-scroll/shared-utils' 6 | describe('DirectionLock Class tests', () => { 7 | let directionLock: DirectionLock 8 | let e = new Event('touchstart') as any 9 | 10 | beforeEach(() => { 11 | directionLock = new DirectionLock(5, false, '') 12 | }) 13 | 14 | it('should call reset when call constructor function', () => { 15 | expect(directionLock.directionLocked).toBe('') 16 | }) 17 | 18 | it('should lock vertically when scrolled in direction Y', () => { 19 | directionLock.checkMovingDirection(0, 20, e) 20 | 21 | expect(directionLock.directionLocked).toBe('vertical') 22 | }) 23 | 24 | it('should lock horizontally when scrolled in direction X', () => { 25 | directionLock.checkMovingDirection(20, 0, e) 26 | 27 | expect(directionLock.directionLocked).toBe('horizontal') 28 | }) 29 | 30 | it('should no lock when freeScroll is true', () => { 31 | directionLock.freeScroll = true 32 | directionLock.checkMovingDirection(20, 20, e) 33 | 34 | expect(directionLock.directionLocked).toBe('') 35 | }) 36 | 37 | it('adjustDelta() ', () => { 38 | directionLock.directionLocked = DirectionLockEnum.Horizontal 39 | const ret1 = directionLock.adjustDelta(20, 20) 40 | expect(ret1).toMatchObject({ 41 | deltaX: 20, 42 | deltaY: 0, 43 | }) 44 | 45 | directionLock.directionLocked = DirectionLockEnum.Vertical 46 | const ret2 = directionLock.adjustDelta(20, 20) 47 | expect(ret2).toMatchObject({ 48 | deltaX: 0, 49 | deltaY: 20, 50 | }) 51 | }) 52 | 53 | it('reset()', () => { 54 | directionLock.directionLocked = DirectionLockEnum.Vertical 55 | directionLock.reset() 56 | expect(directionLock.directionLocked).toBe(DirectionLockEnum.Default) 57 | }) 58 | 59 | it('checkMovingDirection()', () => { 60 | directionLock.directionLocked = DirectionLockEnum.Horizontal 61 | directionLock.eventPassthrough = DirectionLockEnum.Horizontal 62 | const ret1 = directionLock.checkMovingDirection(20, 20, { 63 | preventDefault() { 64 | return true 65 | }, 66 | } as any) 67 | expect(ret1).toBe(true) 68 | 69 | directionLock.directionLocked = DirectionLockEnum.Horizontal 70 | directionLock.eventPassthrough = DirectionLockEnum.Vertical 71 | const ret2 = directionLock.checkMovingDirection(20, 20, { 72 | preventDefault() { 73 | return true 74 | }, 75 | } as any) 76 | expect(ret2).toBe(false) 77 | 78 | // no locked 79 | directionLock.directionLocked = DirectionLockEnum.Default 80 | const ret3 = directionLock.checkMovingDirection(20, 20, { 81 | preventDefault() { 82 | return true 83 | }, 84 | } as any) 85 | expect(ret3).toBe(false) 86 | }) 87 | }) 88 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/BScroll.d.ts: -------------------------------------------------------------------------------- 1 | import { BScrollInstance } from './Instance'; 2 | import { Options, DefOptions, OptionsConstructor } from './Options'; 3 | import Scroller from './scroller/Scroller'; 4 | import { ApplyOrder, EventEmitter } from '@better-scroll/shared-utils'; 5 | import { UnionToIntersection } from './utils/typesHelper'; 6 | interface PluginCtor { 7 | pluginName: string; 8 | applyOrder?: ApplyOrder; 9 | new (scroll: BScroll): any; 10 | } 11 | interface PluginItem { 12 | name: string; 13 | applyOrder?: ApplyOrder.Pre | ApplyOrder.Post; 14 | ctor: PluginCtor; 15 | } 16 | interface PluginsMap { 17 | [key: string]: boolean; 18 | } 19 | interface PropertyConfig { 20 | key: string; 21 | sourceKey: string; 22 | } 23 | declare type ElementParam = HTMLElement | string; 24 | export interface MountedBScrollHTMLElement extends HTMLElement { 25 | isBScrollContainer?: boolean; 26 | } 27 | export declare class BScrollConstructor extends EventEmitter { 28 | static plugins: PluginItem[]; 29 | static pluginsMap: PluginsMap; 30 | scroller: Scroller; 31 | options: OptionsConstructor; 32 | hooks: EventEmitter; 33 | plugins: { 34 | [name: string]: any; 35 | }; 36 | wrapper: HTMLElement; 37 | content: HTMLElement; 38 | [key: string]: any; 39 | static use(ctor: PluginCtor): typeof BScrollConstructor; 40 | constructor(el: ElementParam, options?: Options & O); 41 | setContent(wrapper: MountedBScrollHTMLElement): { 42 | valid: boolean; 43 | contentChanged: boolean; 44 | }; 45 | private init; 46 | private applyPlugins; 47 | private handleAutoBlur; 48 | private eventBubbling; 49 | private refreshWithoutReset; 50 | proxy(propertiesConfig: PropertyConfig[]): void; 51 | refresh(): void; 52 | enable(): void; 53 | disable(): void; 54 | destroy(): void; 55 | eventRegister(names: string[]): void; 56 | } 57 | export interface BScrollConstructor extends BScrollInstance { 58 | } 59 | export interface CustomAPI { 60 | [key: string]: {}; 61 | } 62 | declare type ExtractAPI = { 63 | [K in keyof O]: K extends string ? DefOptions[K] extends undefined ? CustomAPI[K] : never : never; 64 | }[keyof O]; 65 | export declare function createBScroll(el: ElementParam, options?: Options & O): BScrollConstructor & UnionToIntersection>; 66 | export declare namespace createBScroll { 67 | var use: typeof BScrollConstructor.use; 68 | var plugins: PluginItem[]; 69 | var pluginsMap: PluginsMap; 70 | } 71 | declare type createBScroll = typeof createBScroll; 72 | export interface BScrollFactory extends createBScroll { 73 | new (el: ElementParam, options?: Options & O): BScrollConstructor & UnionToIntersection>; 74 | } 75 | export declare type BScroll = BScrollConstructor & UnionToIntersection>; 76 | export declare const BScroll: BScrollFactory; 77 | export {}; 78 | -------------------------------------------------------------------------------- /components/nav-bar/nav-bar.nvue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 78 | 79 | 135 | -------------------------------------------------------------------------------- /components/bubble/bubble.nvue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 91 | 92 | 124 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/__utils__/event.ts: -------------------------------------------------------------------------------- 1 | export function createEvent(type: string, name: string): Event { 2 | const e = document.createEvent(type || 'Event') 3 | e.initEvent(name, true, true) 4 | return e 5 | } 6 | 7 | interface CustomClickEvent extends MouseEvent { 8 | pageX: number 9 | pageY: number 10 | } 11 | 12 | export function dispatchClick(target: EventTarget, name = 'click') { 13 | const event = createEvent('', name) 14 | event.pageX = 0 15 | event.pageY = 0 16 | target.dispatchEvent(event) 17 | } 18 | 19 | interface CustomTouch { 20 | pageX: number 21 | pageY: number 22 | } 23 | type CustomTouches = CustomTouch[] | CustomTouch 24 | 25 | export interface CustomTouchEvent extends Event { 26 | touches: CustomTouches 27 | targetTouches: CustomTouches 28 | changedTouches: CustomTouches 29 | } 30 | 31 | interface CustomMouseEvent extends Event { 32 | button: 0 | 1 33 | pageX: number 34 | pageY: number 35 | } 36 | 37 | export function dispatchTouch( 38 | target: EventTarget, 39 | name = 'touchstart', 40 | touches: CustomTouches 41 | ): void { 42 | const event = createEvent('', name) 43 | event.touches = event.targetTouches = event.changedTouches = touches 44 | target.dispatchEvent(event) 45 | } 46 | 47 | export function dispatchMouse( 48 | target: EventTarget, 49 | name = 'mousedown', 50 | useLeftButton = true 51 | ): void { 52 | const event = createEvent('', name) 53 | event.button = useLeftButton ? 0 : 1 54 | event.pageX = 0 55 | event.pageY = 0 56 | target.dispatchEvent(event) 57 | } 58 | 59 | export function dispatchTouchStart( 60 | target: EventTarget, 61 | touches: CustomTouches 62 | ): void { 63 | dispatchTouch(target, 'touchstart', touches) 64 | } 65 | 66 | export function dispatchTouchMove( 67 | target: EventTarget, 68 | touches: CustomTouches 69 | ): void { 70 | dispatchTouch(target, 'touchmove', touches) 71 | } 72 | 73 | export function dispatchTouchEnd( 74 | target: EventTarget, 75 | touches: CustomTouches 76 | ): void { 77 | dispatchTouch(target, 'touchend', touches) 78 | } 79 | 80 | export function dispatchTouchCancel( 81 | target: EventTarget, 82 | touches: CustomTouches 83 | ): void { 84 | dispatchTouch(target, 'touchcancel', touches) 85 | } 86 | 87 | export function dispatchSwipe( 88 | target: EventTarget, 89 | touches: CustomTouches, 90 | duration: number, 91 | cb: () => any 92 | ): void { 93 | // TODO 优化写法 94 | if (!Array.isArray(touches)) { 95 | touches = [touches] 96 | } 97 | if (touches instanceof Array) { 98 | dispatchTouchStart(target, touches[0]) 99 | const moveAndEnd = () => { 100 | if (touches instanceof Array) { 101 | dispatchTouchMove(target, touches[1] || touches[0]) 102 | dispatchTouchEnd(target, touches[2] || touches[1] || touches[0]) 103 | } 104 | cb && cb() 105 | } 106 | if (duration) { 107 | setTimeout(moveAndEnd, duration) 108 | } else { 109 | moveAndEnd() 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/__utils__/layout.ts: -------------------------------------------------------------------------------- 1 | export interface CustomHTMLDivElement extends HTMLDivElement { 2 | clientWidth: number 3 | clientHeight: number 4 | offsetWidth: number 5 | offsetHeight: number 6 | offsetTop: number 7 | offsetLeft: number 8 | _jsdomMockClientWidth?: number 9 | _jsdomMockClientHeight?: number 10 | _jsdomMockOffsetWidth?: number 11 | _jsdomMockOffsetHeight?: number 12 | _jsdomMockOffsetTop?: number 13 | _jsdomMockOffsetLeft?: number 14 | [key: string]: any 15 | } 16 | 17 | function firstUpper(key: string) { 18 | return key.charAt(0).toUpperCase() + key.slice(1) 19 | } 20 | 21 | function genMockPrototype(mockName: string) { 22 | return { 23 | get: jest.fn().mockImplementation(dom => { 24 | return Number(dom.getAttribute(mockName)) 25 | }) 26 | } 27 | } 28 | 29 | function mockHTMLPrototype(propName: string, mockGetter: jest.Mock) { 30 | Object.defineProperty(HTMLElement.prototype, propName, { 31 | get: function() { 32 | return mockGetter(this) 33 | }, 34 | configurable: true 35 | }) 36 | } 37 | 38 | export function mockDomOffset( 39 | dom: CustomHTMLDivElement, 40 | offsetObj: { 41 | width?: number 42 | height?: number 43 | top?: number 44 | left?: number 45 | [key: string]: any 46 | } 47 | ) { 48 | Object.keys(offsetObj).forEach(key => { 49 | const mockName = `_jsdomMockOffset${firstUpper(key)}` 50 | dom.setAttribute(mockName, offsetObj[key]) 51 | }) 52 | } 53 | 54 | export function mockDomClient( 55 | dom: CustomHTMLDivElement, 56 | clientObj: { 57 | width?: number 58 | height?: number 59 | [key: string]: any 60 | } 61 | ) { 62 | Object.keys(clientObj).forEach(key => { 63 | const mockName = `_jsdomMockClient${firstUpper(key)}` 64 | dom.setAttribute(mockName, clientObj[key]) 65 | }) 66 | } 67 | 68 | export function createDiv( 69 | width: number = 0, 70 | height: number = 0, 71 | top: number = 0, 72 | left: number = 0 73 | ) { 74 | const dom = document.createElement('div') as CustomHTMLDivElement 75 | mockDomOffset(dom, { 76 | width, 77 | height, 78 | top, 79 | left 80 | }) 81 | mockDomClient(dom, { 82 | width, 83 | height 84 | }) 85 | return dom 86 | } 87 | 88 | export const mockClientWidth = genMockPrototype('_jsdomMockClientWidth') 89 | mockHTMLPrototype('clientWidth', mockClientWidth.get) 90 | 91 | export const mockClientHeight = genMockPrototype('_jsdomMockClientHeight') 92 | mockHTMLPrototype('clientHeight', mockClientHeight.get) 93 | 94 | export const mockOffsetWidth = genMockPrototype('_jsdomMockOffsetWidth') 95 | mockHTMLPrototype('offsetWidth', mockOffsetWidth.get) 96 | 97 | export const mockOffsetHeight = genMockPrototype('_jsdomMockOffsetHeight') 98 | mockHTMLPrototype('offsetHeight', mockOffsetHeight.get) 99 | 100 | export const mockOffsetTop = genMockPrototype('_jsdomMockOffsetTop') 101 | mockHTMLPrototype('offsetTop', mockOffsetTop.get) 102 | 103 | export const mockOffsetLeft = genMockPrototype('_jsdomMockOffsetLeft') 104 | mockHTMLPrototype('offsetLeft', mockOffsetLeft.get) 105 | -------------------------------------------------------------------------------- /store/modules/music.js: -------------------------------------------------------------------------------- 1 | import Utils from '@/assets/js/util.js'; 2 | const { indexOf, suffix, dateFormat, removeSuffix, randomString } = Utils; 3 | 4 | import { 5 | MUSICPATH, 6 | PLAYLIST, 7 | PLAYMODE, 8 | PLAYRECORD, 9 | MUSICSOURCES, 10 | MUSICLYRICSHOW } from '../config.js' 11 | 12 | const state = { 13 | musicPath: uni.getStorageSync(MUSICPATH) || '', //默认访问的本地音乐资源路径 14 | musicPlayList: uni.getStorageSync(PLAYLIST) || [], //音乐播放列表 15 | musicPlayMode: uni.getStorageSync(PLAYMODE) || 'loop', //音乐播放模式 loop => 循环播放 once => 单曲循环 random => 乱序播放 16 | musicPlayRecord: uni.getStorageSync(PLAYRECORD) || '', //音乐播放记录 17 | musicLyricShow: uni.getStorageSync(MUSICLYRICSHOW) || false, //控制歌词显示 18 | musicSourcesController: uni.getStorageSync(MUSICSOURCES) || [] //在线音乐来源控制,放进来的表示关闭获取此来源的音乐 19 | } 20 | 21 | const getters = { 22 | musicPathHistory (state) { 23 | return state.musicPath 24 | }, 25 | playList (state) { 26 | return state.musicPlayList 27 | }, 28 | getMusicPlayMode (state) { 29 | return state.musicPlayMode 30 | }, 31 | getMusicPlayRecord (state) { 32 | return state.musicPlayRecord 33 | }, 34 | getMusicSourcesController (state) { 35 | return state.musicSourcesController 36 | }, 37 | getMusicLyricShow (state) { 38 | return state.musicLyricShow 39 | } 40 | } 41 | 42 | const mutations = { 43 | //新增歌曲 44 | addMusic (state, music) { 45 | for ( let i in music ) { 46 | state.musicPlayList.push({ 47 | name: removeSuffix(music[i].name), 48 | image: music[i].image ? music[i].image : '/static/music/music-bg.jpg', 49 | singer: music[i].singer || '未知歌手' , 50 | path: music[i].path, 51 | lyric: music[i].lyric || false, 52 | source: music[i].source ? music[i].source : 'local' 53 | }) 54 | } 55 | uni.setStorageSync(PLAYLIST, state.musicPlayList); 56 | }, 57 | //删除指定歌曲 58 | deleteMusic (state, path) { 59 | let flag = indexOf(state.musicPlayList, 'path', path); 60 | if ( flag > -1 ) { 61 | state.musicPlayList.splice(flag, 1); 62 | uni.setStorageSync(PLAYLIST, state.musicPlayList) 63 | } 64 | }, 65 | //清空所有歌曲 66 | clearMusic (state, type) { 67 | state.musicPlayList = []; 68 | uni.setStorageSync(PLAYLIST, state.musicPlayList); 69 | state.musicPlayRecord = ''; 70 | uni.setStorageSync(PLAYRECORD, state.musicPlayRecord); 71 | state.musicPlayTime = 0; 72 | state.musicPlayDuration = 0; 73 | }, 74 | //更新音乐播放记录 75 | updateMusicPlayRecord (state, record) { 76 | state.musicPlayRecord = record; 77 | uni.setStorageSync(PLAYRECORD, state.musicPlayRecord); 78 | }, 79 | //改变音乐播放模式 80 | changeMusicPlayMode (state, mode) { 81 | state.musicPlayMode = mode; 82 | uni.setStorageSync(PLAYMODE, state.musicPlayMode); 83 | }, 84 | //更新本地音乐上次访问文件夹位置 85 | updateMusicPath (state, path) { 86 | state.musicPath = path; 87 | uni.setStorageSync(MUSICPATH, state.musicPath); 88 | }, 89 | //设置歌词是否展示 90 | setMusicLyricShow (state, bool) { 91 | state.musicLyricShow = bool; 92 | uni.setStorageSync(MUSICLYRICSHOW, state.musicLyricShow); 93 | }, 94 | //设置在线音乐来源 95 | setMusicSourcesController (state, sources) { 96 | state.musicSourcesController = sources; 97 | uni.setStorageSync(MUSICSOURCES, state.musicSourcesController); 98 | } 99 | } 100 | 101 | export default { 102 | namespaced: true, 103 | state, 104 | getters, 105 | mutations 106 | } -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/Instance.ts: -------------------------------------------------------------------------------- 1 | import { Behavior } from './scroller/Behavior' 2 | import Actions from './scroller/Actions' 3 | import { ExposedAPI as ExposedAPIByScroller } from './scroller/Scroller' 4 | import { Animater } from './animater' 5 | import { ExposedAPI as ExposedAPIByAnimater } from './animater/Base' 6 | 7 | export interface BScrollInstance 8 | extends ExposedAPIByScroller, 9 | ExposedAPIByAnimater { 10 | [key: string]: any 11 | x: Behavior['currentPos'] 12 | y: Behavior['currentPos'] 13 | hasHorizontalScroll: Behavior['hasScroll'] 14 | hasVerticalScroll: Behavior['hasScroll'] 15 | scrollerWidth: Behavior['contentSize'] 16 | scrollerHeight: Behavior['contentSize'] 17 | maxScrollX: Behavior['maxScrollPos'] 18 | maxScrollY: Behavior['maxScrollPos'] 19 | minScrollX: Behavior['minScrollPos'] 20 | minScrollY: Behavior['minScrollPos'] 21 | movingDirectionX: Behavior['movingDirection'] 22 | movingDirectionY: Behavior['movingDirection'] 23 | directionX: Behavior['direction'] 24 | directionY: Behavior['direction'] 25 | enabled: Actions['enabled'] 26 | pending: Animater['pending'] 27 | } 28 | 29 | export const propertiesConfig = [ 30 | { 31 | sourceKey: 'scroller.scrollBehaviorX.currentPos', 32 | key: 'x' 33 | }, 34 | { 35 | sourceKey: 'scroller.scrollBehaviorY.currentPos', 36 | key: 'y' 37 | }, 38 | { 39 | sourceKey: 'scroller.scrollBehaviorX.hasScroll', 40 | key: 'hasHorizontalScroll' 41 | }, 42 | { 43 | sourceKey: 'scroller.scrollBehaviorY.hasScroll', 44 | key: 'hasVerticalScroll' 45 | }, 46 | { 47 | sourceKey: 'scroller.scrollBehaviorX.contentSize', 48 | key: 'scrollerWidth' 49 | }, 50 | { 51 | sourceKey: 'scroller.scrollBehaviorY.contentSize', 52 | key: 'scrollerHeight' 53 | }, 54 | { 55 | sourceKey: 'scroller.scrollBehaviorX.maxScrollPos', 56 | key: 'maxScrollX' 57 | }, 58 | { 59 | sourceKey: 'scroller.scrollBehaviorY.maxScrollPos', 60 | key: 'maxScrollY' 61 | }, 62 | { 63 | sourceKey: 'scroller.scrollBehaviorX.minScrollPos', 64 | key: 'minScrollX' 65 | }, 66 | { 67 | sourceKey: 'scroller.scrollBehaviorY.minScrollPos', 68 | key: 'minScrollY' 69 | }, 70 | { 71 | sourceKey: 'scroller.scrollBehaviorX.movingDirection', 72 | key: 'movingDirectionX' 73 | }, 74 | { 75 | sourceKey: 'scroller.scrollBehaviorY.movingDirection', 76 | key: 'movingDirectionY' 77 | }, 78 | { 79 | sourceKey: 'scroller.scrollBehaviorX.direction', 80 | key: 'directionX' 81 | }, 82 | { 83 | sourceKey: 'scroller.scrollBehaviorY.direction', 84 | key: 'directionY' 85 | }, 86 | { 87 | sourceKey: 'scroller.actions.enabled', 88 | key: 'enabled' 89 | }, 90 | { 91 | sourceKey: 'scroller.animater.pending', 92 | key: 'pending' 93 | }, 94 | { 95 | sourceKey: 'scroller.animater.stop', 96 | key: 'stop' 97 | }, 98 | { 99 | sourceKey: 'scroller.scrollTo', 100 | key: 'scrollTo' 101 | }, 102 | { 103 | sourceKey: 'scroller.scrollBy', 104 | key: 'scrollBy' 105 | }, 106 | { 107 | sourceKey: 'scroller.scrollToElement', 108 | key: 'scrollToElement' 109 | }, 110 | { 111 | sourceKey: 'scroller.resetPosition', 112 | key: 'resetPosition' 113 | } 114 | ] 115 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/pull-up/dist/pull-up.min.js: -------------------------------------------------------------------------------- 1 | !function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).PullUp=o()}(this,function(){"use strict";var n="undefined"!=typeof window,o=n&&navigator.userAgent.toLowerCase();o&&/wechatdevtools/.test(o),o&&o.indexOf("android"),function(){if("string"==typeof o){var t=/os (\d\d?_\d(_\d)?)/.exec(o);if(!t)return;t=t[1].split("_").map(function(t){return parseInt(t,10)});13===t[0]&&t[1]}}();if(n)try{var t={};Object.defineProperty(t,"passive",{get:function(){}}),window.addEventListener("test-passive",function(){},t)}catch(t){}var s=n&&document.createElement("div").style,i=function(){if(!n)return!1;for(var t=0,o=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];t { 40 | let now = getNow() 41 | // js animation end 42 | if (now >= destTime) { 43 | this.translate(endPoint) 44 | if (isRealtimeProbeType) { 45 | this.hooks.trigger(this.hooks.eventTypes.move, endPoint) 46 | } 47 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint) 48 | return 49 | } 50 | 51 | now = (now - startTime) / duration 52 | let easing = easingFn(now) 53 | const newPoint = {} as TranslaterPoint 54 | Object.keys(endPoint).forEach((key) => { 55 | const startValue = startPoint[key] 56 | const endValue = endPoint[key] 57 | newPoint[key] = (endValue - startValue) * easing + startValue 58 | }) 59 | this.translate(newPoint) 60 | 61 | if (isRealtimeProbeType) { 62 | this.hooks.trigger(this.hooks.eventTypes.move, newPoint) 63 | } 64 | 65 | if (this.pending) { 66 | this.timer = requestAnimationFrame(step) 67 | } 68 | 69 | // call bs.stop() should not dispatch end hook again. 70 | // forceStop hook will do this. 71 | /* istanbul ignore if */ 72 | if (!this.pending) { 73 | if (this.callStopWhenPending) { 74 | this.callStopWhenPending = false 75 | } else { 76 | // raf ends should dispatch end hook. 77 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint) 78 | } 79 | } 80 | } 81 | 82 | this.setPending(true) 83 | // when manually call bs.stop(), then bs.scrollTo() 84 | // we should reset callStopWhenPending to dispatch end hook 85 | if (this.callStopWhenPending) { 86 | this.setCallStop(false) 87 | } 88 | cancelAnimationFrame(this.timer) 89 | step() 90 | } 91 | 92 | doStop(): boolean { 93 | const pending = this.pending 94 | this.setForceStopped(false) 95 | this.setCallStop(false) 96 | // still in requestFrameAnimation 97 | if (pending) { 98 | this.setPending(false) 99 | cancelAnimationFrame(this.timer) 100 | const pos = this.translater.getComputedPosition() 101 | this.setForceStopped(true) 102 | this.setCallStop(true) 103 | 104 | this.hooks.trigger(this.hooks.eventTypes.forceStop, pos) 105 | } 106 | return pending 107 | } 108 | 109 | stop() { 110 | const stopFromAnimation = this.doStop() 111 | if (stopFromAnimation) { 112 | this.hooks.trigger(this.hooks.eventTypes.callStop) 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | ## 2.9.8.5(2021-10-19) 2 | * 更新阅读插件 3 | * 修复显示一些图片app会卡死的问题 4 | * 优化部分图片缓存问题 5 | ## 2.9.8.4(2021-10-14) 6 | * 新增小说接口 7 | * 添加青少年模式 8 | * 接入最新版阅读插件 9 | * 添加在线小说阅读页面进度条显示 10 | ## 2.9.8.3(2021-09-22) 11 | * 修复阅读在线小说有时部分页面不显示的bug 12 | * 修复在线小说阅读新章节时会继承上次阅读章节的阅读位置的bug 13 | * 更改音乐播放全局控件样式,更改播放列表样式 14 | ## 2.9.8.2(2021-09-17) 15 | * 修复某个漫画接口不能显示图片的问题 16 | * 修改了在线小说内容获取方式 17 | * 修改了在线漫画内容获取方式 18 | * 删除了一个漫画接口 19 | ## 2.9.81(2021-09-08) 20 | * 修复了漫画阅读页面不能切换章节的问题 21 | * 现在将获取本地小说文本内容的原生方法封装成了插件,同时获取文件列表的方法也使用native.js方法获取,如果你不需要阅读本地漫画,就可以直接云打包 22 | ## 2.9.8(2021-09-06) 23 | * 修复阅读本地小说到最后会从开始重新排版的bug 24 | * 修复阅读小说设置窗口可能打不开的bug 25 | ## 2.9.7(2021-09-04) 26 | * 新增在线小说接口 27 | * 修复部分在线漫画接口 28 | * 优化了代码格式 29 | * 优化了文件结构 30 | ## 2.9.6(2021-08-28) 31 | * 更新了失效的音乐搜索接口 32 | * 将文件搜索列表独立成组件 33 | * 更新了获取漫画内容的方式 34 | * 更新小说分页组件,现在被独立成一个插件,大家可以去看看我新发布的分页插件[小说阅读分页插件](https://ext.dcloud.net.cn/plugin?id=6026) 35 | ## 2.9.5(2021-06-14) 36 | * 新增小说编辑功能,非常适合发现有错别字并且有强迫症的人 37 | * 一些组件添加了点击交互效果 38 | * 本地小说搜索页替换了新的获取文件的方法,不再调用原生方法,但还有某些问题,想要使用原生方法的可以使用同文件夹下的副本页面 39 | ## 2.9.4(2021-04-06) 40 | * 1、新增一个在线音乐接口 41 | * 2、修复和优化问题若干 42 | ## 2.9.3(2021-03-23) 43 | * 1、新增音乐播放界面 44 | * 2、新增歌词显示功能 45 | * 3、新增全局歌词显示功能 46 | * 4、修改了播放列表样式 47 | * ps(需要注意此次更新修改了音乐数据的格式,所以打包apk安装之前,请将原本保存的歌曲先清空掉,避免出现bug) 48 | ## 2.9.0(2021-03-18) 49 | * 1、新增2个获取在线漫画的来源 50 | * 2、新增获取在线音乐的接口 51 | * 3、设置页面新增控制在线音乐和在线漫画来源的按钮 52 | * 4、修复若干bug 53 | ## 2.8.4(2021-02-27) 54 | * 1、修复一些显示bug 55 | * 2、优化漫画图片尺寸问题 56 | * 3、优化一些漫画阅读细节问题 57 | ## 2.8.2(2021-02-21) 58 | * 1、修改漫画阅读页图片尺寸不对的问题 59 | * 2、修复获取在线漫画内容开头闪屏的问题 60 | * 3、修复在线漫画搜索页搜索框清空内容会触发搜索事件的问题 61 | * 4、修复在线漫画会出现已读完的问题 62 | ## 2.8.0(2021-02-20) 63 | * 1、新增一个添加在线漫画的接口 64 | * 2、新增一个漫画详情页面 65 | * 3、新增一个获取漫画详情信息的接口 66 | * 4、新增一个html页面用于获取漫画内容 67 | ## 2.7.5(2021-01-05) 68 | * 1、优化翻页方式切换逻辑 69 | * 2、将弹出确认框做成全局方法,并优化样式 70 | * 3、将弹出选择框做成全局方法,并优化样式 71 | ## 2.7.0(2020-12-26) 72 | * 1、小说阅读方式新增 【伪·仿真翻页】【覆盖翻页】(ps: 因为只能横向翻页,所以叫伪·仿真翻页) 73 | * 2、修复首页书籍之间间隔不一样的问题 74 | * 3、修复音乐列表名称过长没有隐藏的问题 75 | * 4、优化路由跳转代码,将路由跳转的代码写在公共方法中 76 | ## 2.6.1(2020-11-24) 77 | * 优化长列表,减少白屏时间 78 | * 不知道是不是错觉,总感觉优化后变卡了,哪位测试过麻烦告诉我一下 79 | ## 2.6.0(2020-11-23) 80 | * 新增文件分享功能,可以在添加小说,音乐,漫画页面分享文件 81 | * ps(只支持单文件分享) 82 | ## 2.5.1(2020-11-20) 83 | * 优化音乐控件的触摸事件,解决点击和拖动的冲突 84 | ## 2.5.0(2020-11-19) 85 | * 新增音乐播放功能,只支持应用内播放 86 | ## 2.1.0(2020-11-16) 87 | * 1、修改原生方法,新增生成缩略图的方法,现在读取漫画列表时,会在每本漫画一级文件夹下生成一张叫做 “000_preview.jpg” 的图片,是由漫画第一张图片压缩成的,这样做是为了减少手机内存负担 88 | * 2、新增获取扩展内存卡的方法,但不适配所有手机 89 | ## 2.0.5(2020-11-13) 90 | * 1、新增读取漫画内容和漫画列表的原生方法,提升了读取漫画内容的速度 91 | * 2、修复了添加小说页面直接阅读小说,进度显示NaN的bug 92 | * 3、删除了漫画阅读页面夜间模式下亮度会降低的设置 93 | * 4、修复了旋转屏幕后,图片高度异常的bug 94 | ## 2.0.0(2020-11-12) 95 | * 1、新增阅读本地漫画的功能 96 | * ps: 漫画资源结构有2种,分别为: 97 | - 1、漫画文件夹 => 漫画图片 98 | - 2、漫画文件夹 => 章节文件夹 => 漫画图片; 99 | - 3、如果漫画文件夹下同时存在图片和文件夹,以文件夹优先,会忽略图片。 100 | * 2、更改了关于页面内容 101 | * 3、更改了原生方法,如果要打包的朋友,注意替换原生方法 102 | * 4、与读取小说内容一样,读取漫画内容也分调试用的方法和正式打包使用的方法,都是注释好了的,根据情况选择使用 103 | ## 1.2.5(2020-11-02) 104 | * 1、优化了列表组件和导航栏组件的代码,去除了不必要的传参 105 | * 2、修复了阅读页文本有时右边会超出一部分的bug 106 | * 3、修改了首页书籍列表展示布局 107 | * 4、修复了阅读页拖动进度条到100%时,无法点击回上一页的bug 108 | ## 1.2.0(2020-10-21) 109 | * 1、新增滑动阅读功能分为上下滑动和左右滑动同时保留点击翻页 110 | * 2、开放设置界面,用于设置阅读方式和动画时间 111 | * 3、此版本几乎重构了整个阅读页,如果要打包安装的朋友请将原本的版本数据清空 112 | ## 1.1.0(2020-10-12) 113 | * 1、将阅读页面设置窗口改为原生子窗体,现在设置窗口的滑入和滑出动画更加流畅 114 | * 2、修复访问文件夹时滚动条位置不变的bug 115 | * 3、修复进度条拖动bug 116 | ## 1.0.2(2020-10-09) 117 | * 1、修复了首页和本地文件页面,不能搜索的bug 118 | * 2、本地文件页面也能直接读取txt文件内容 119 | * 3、稍微优化了下自定义列表组件的代码 120 | * 4、除了原生的弹框,其余自定义组件的弹窗都适配了夜间模式 121 | * 5、优化了删除提示,删除单个文件时,会提示文件名称,避免删错文件 122 | ## 1.0.0(2020-09-29) 123 | * 主要功能: 124 | * 1、首页显示本地导入的小说列表(显示信息包括(阅读进度、导入时间,小说名称)) 125 | * 2、可拖曳的抽屉菜单(效果不是很好) 126 | * 3、搜索本地txt文件列表 127 | * 4、导入本地txt文档 128 | * 5、删除txt文件 129 | * 6、小说左右分页阅读(只有左右分页且没有动画效果) 130 | * 7、可以跳转进度阅读小说 131 | * 8、查看小说章节,如果小说的章节格式符合规格的话 132 | * 9、保存书签,显示书签列表 133 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/dist/types/Options.d.ts: -------------------------------------------------------------------------------- 1 | import { Quadrant } from '@better-scroll/shared-utils'; 2 | export declare type Tap = 'tap' | ''; 3 | export declare type BounceOptions = Partial | boolean; 4 | export declare type DblclickOptions = Partial | boolean; 5 | export interface BounceConfig { 6 | top: boolean; 7 | bottom: boolean; 8 | left: boolean; 9 | right: boolean; 10 | } 11 | export interface DblclickConfig { 12 | delay: number; 13 | } 14 | export interface CustomOptions { 15 | } 16 | export interface DefOptions { 17 | [key: string]: any; 18 | startX?: number; 19 | startY?: number; 20 | scrollX?: boolean; 21 | scrollY?: boolean; 22 | freeScroll?: boolean; 23 | directionLockThreshold?: number; 24 | eventPassthrough?: string; 25 | click?: boolean; 26 | tap?: Tap; 27 | bounce?: BounceOptions; 28 | bounceTime?: number; 29 | momentum?: boolean; 30 | momentumLimitTime?: number; 31 | momentumLimitDistance?: number; 32 | swipeTime?: number; 33 | swipeBounceTime?: number; 34 | deceleration?: number; 35 | flickLimitTime?: number; 36 | flickLimitDistance?: number; 37 | resizePolling?: number; 38 | probeType?: number; 39 | stopPropagation?: boolean; 40 | preventDefault?: boolean; 41 | preventDefaultException?: { 42 | tagName?: RegExp; 43 | className?: RegExp; 44 | }; 45 | tagException?: { 46 | tagName?: RegExp; 47 | className?: RegExp; 48 | }; 49 | HWCompositing?: boolean; 50 | useTransition?: boolean; 51 | bindToWrapper?: boolean; 52 | bindToTarget?: boolean; 53 | disableMouse?: boolean; 54 | disableTouch?: boolean; 55 | autoBlur?: boolean; 56 | translateZ?: string; 57 | dblclick?: DblclickOptions; 58 | autoEndDistance?: number; 59 | outOfBoundaryDampingFactor?: number; 60 | specifiedIndexAsContent?: number; 61 | quadrant?: Quadrant; 62 | } 63 | export interface Options extends DefOptions, CustomOptions { 64 | } 65 | export declare class CustomOptions { 66 | } 67 | export declare class OptionsConstructor extends CustomOptions implements DefOptions { 68 | [key: string]: any; 69 | startX: number; 70 | startY: number; 71 | scrollX: boolean; 72 | scrollY: boolean; 73 | freeScroll: boolean; 74 | directionLockThreshold: number; 75 | eventPassthrough: string; 76 | click: boolean; 77 | tap: Tap; 78 | bounce: BounceConfig; 79 | bounceTime: number; 80 | momentum: boolean; 81 | momentumLimitTime: number; 82 | momentumLimitDistance: number; 83 | swipeTime: number; 84 | swipeBounceTime: number; 85 | deceleration: number; 86 | flickLimitTime: number; 87 | flickLimitDistance: number; 88 | resizePolling: number; 89 | probeType: number; 90 | stopPropagation: boolean; 91 | preventDefault: boolean; 92 | preventDefaultException: { 93 | tagName?: RegExp; 94 | className?: RegExp; 95 | }; 96 | tagException: { 97 | tagName?: RegExp; 98 | className?: RegExp; 99 | }; 100 | HWCompositing: boolean; 101 | useTransition: boolean; 102 | bindToWrapper: boolean; 103 | bindToTarget: boolean; 104 | disableMouse: boolean; 105 | disableTouch: boolean; 106 | autoBlur: boolean; 107 | translateZ: string; 108 | dblclick: DblclickOptions; 109 | autoEndDistance: number; 110 | outOfBoundaryDampingFactor: number; 111 | specifiedIndexAsContent: number; 112 | quadrant: Quadrant; 113 | constructor(); 114 | merge(options?: Options): this; 115 | process(): this; 116 | resolveBounce(bounceOptions: BounceOptions): BounceConfig; 117 | } 118 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/__tests__/index.spec.ts: -------------------------------------------------------------------------------- 1 | import BScroll from '../index' 2 | 3 | describe('BetterScroll Core', () => { 4 | let bscroll: BScroll 5 | let wrapper = document.createElement('div') 6 | let content = document.createElement('p') 7 | wrapper.appendChild(content) 8 | beforeEach(() => { 9 | bscroll = new BScroll(wrapper, {}) 10 | }) 11 | afterEach(() => { 12 | BScroll.plugins = [] 13 | BScroll.pluginsMap = {} 14 | }) 15 | 16 | it('use()', () => { 17 | const plugin = class MyPlugin { 18 | static pluginName = 'myPlugin' 19 | } 20 | BScroll.use(plugin) 21 | // has installed 22 | BScroll.use(plugin) 23 | 24 | expect(BScroll.plugins.length).toBe(1) 25 | 26 | // Plugin should specify pluginName 27 | const spyFn = jest.spyOn(console, 'error') 28 | const unnamedPlugin = class UnnamedPlugin {} 29 | BScroll.use(unnamedPlugin as any) 30 | expect(spyFn).toBeCalled() 31 | spyFn.mockRestore() 32 | }) 33 | 34 | it('should init plugins when set top-level of BScroll options', () => { 35 | let mockFn = jest.fn() 36 | const plugin = class MyPlugin { 37 | static pluginName = 'myPlugin2' 38 | constructor(bscroll: BScroll) { 39 | mockFn(bscroll) 40 | } 41 | } 42 | BScroll.use(plugin) 43 | let wrapper = document.createElement('div') 44 | wrapper.appendChild(document.createElement('p')) 45 | 46 | let bs = new BScroll(wrapper, { 47 | myPlugin2: true 48 | }) 49 | expect(mockFn).toBeCalledWith(bs) 50 | }) 51 | 52 | it('should throw error when wrapper is not a ElementNode or wrapper has no children ', () => { 53 | let spy = jest.spyOn(console, 'error') 54 | let bs = new BScroll('.div', {}) 55 | let bs2 = new BScroll(document.createElement('div'), {}) 56 | 57 | expect(spy).toHaveBeenCalled() 58 | expect(spy).toBeCalledTimes(2) 59 | }) 60 | 61 | it('disable()', () => { 62 | const mockFn = jest.fn() 63 | bscroll.on(bscroll.eventTypes.disable, mockFn) 64 | bscroll.hooks.on(bscroll.hooks.eventTypes.disable, mockFn) 65 | bscroll.disable() 66 | 67 | expect(mockFn).toBeCalledTimes(2) 68 | }) 69 | 70 | it('destroy()', () => { 71 | const mockFn = jest.fn() 72 | bscroll.on(bscroll.eventTypes.destroy, mockFn) 73 | bscroll.hooks.on(bscroll.hooks.eventTypes.destroy, mockFn) 74 | bscroll.destroy() 75 | 76 | expect(mockFn).toBeCalledTimes(2) 77 | }) 78 | 79 | it('eventRegister()', () => { 80 | bscroll.eventRegister(['dummy']) 81 | expect(bscroll.eventTypes.dummy).toBeTruthy() 82 | }) 83 | 84 | it('should refresh when window resized', () => { 85 | const mockFn = jest.fn() 86 | bscroll.on(bscroll.eventTypes.refresh, mockFn) 87 | bscroll.scroller.hooks.trigger(bscroll.scroller.hooks.eventTypes.resize) 88 | expect(mockFn).toBeCalledTimes(1) 89 | }) 90 | 91 | it('plugin wanna control scroll position ', () => { 92 | const mockFn = jest.fn().mockImplementation(() => true) 93 | class DummyPlugin { 94 | static pluginName = 'dummy' 95 | constructor(scroll: BScroll) { 96 | scroll.hooks.on(scroll.hooks.eventTypes.beforeInitialScrollTo, mockFn) 97 | } 98 | } 99 | BScroll.use(DummyPlugin) 100 | bscroll = new BScroll(wrapper, { dummy: true }) 101 | expect(mockFn).toBeCalled() 102 | }) 103 | 104 | it('should trigger contentChanged hook when content DOM has changed', () => { 105 | const mockFn = jest.fn() 106 | bscroll.on(bscroll.eventTypes.contentChanged, mockFn) 107 | 108 | // content DOM has 109 | wrapper.removeChild(content) 110 | wrapper.appendChild(document.createElement('div')) 111 | bscroll.refresh() 112 | expect(mockFn).toBeCalled() 113 | }) 114 | }) 115 | -------------------------------------------------------------------------------- /uni_modules/yingbing-ReadPage/node_modules/@better-scroll/core/src/animater/Transition.ts: -------------------------------------------------------------------------------- 1 | import { 2 | style, 3 | requestAnimationFrame, 4 | cancelAnimationFrame, 5 | EaseFn, 6 | Probe, 7 | } from '@better-scroll/shared-utils' 8 | import Base from './Base' 9 | import { TranslaterPoint } from '../translater' 10 | import { isValidPostion } from '../utils/compat' 11 | 12 | export default class Transition extends Base { 13 | startProbe(startPoint: TranslaterPoint, endPoint: TranslaterPoint) { 14 | let prePos = startPoint 15 | const probe = () => { 16 | let pos = this.translater.getComputedPosition() 17 | 18 | if (isValidPostion(startPoint, endPoint, pos, prePos)) { 19 | this.hooks.trigger(this.hooks.eventTypes.move, pos) 20 | } 21 | // call bs.stop() should not dispatch end hook again. 22 | // forceStop hook will do this. 23 | /* istanbul ignore if */ 24 | if (!this.pending) { 25 | if (this.callStopWhenPending) { 26 | this.callStopWhenPending = false 27 | } else { 28 | // transition ends should dispatch end hook. 29 | this.hooks.trigger(this.hooks.eventTypes.end, pos) 30 | } 31 | } 32 | prePos = pos 33 | 34 | if (this.pending) { 35 | this.timer = requestAnimationFrame(probe) 36 | } 37 | } 38 | // when manually call bs.stop(), then bs.scrollTo() 39 | // we should reset callStopWhenPending to dispatch end hook 40 | if (this.callStopWhenPending) { 41 | this.setCallStop(false) 42 | } 43 | 44 | cancelAnimationFrame(this.timer) 45 | probe() 46 | } 47 | 48 | transitionTime(time = 0) { 49 | this.style[style.transitionDuration] = time + 'ms' 50 | this.hooks.trigger(this.hooks.eventTypes.time, time) 51 | } 52 | 53 | transitionTimingFunction(easing: string) { 54 | this.style[style.transitionTimingFunction] = easing 55 | this.hooks.trigger(this.hooks.eventTypes.timeFunction, easing) 56 | } 57 | 58 | transitionProperty() { 59 | this.style[style.transitionProperty] = style.transform 60 | } 61 | 62 | move( 63 | startPoint: TranslaterPoint, 64 | endPoint: TranslaterPoint, 65 | time: number, 66 | easingFn: string | EaseFn 67 | ) { 68 | this.setPending(time > 0) 69 | this.transitionTimingFunction(easingFn as string) 70 | this.transitionProperty() 71 | this.transitionTime(time) 72 | this.translate(endPoint) 73 | 74 | const isRealtimeProbeType = this.options.probeType === Probe.Realtime 75 | 76 | if (time && isRealtimeProbeType) { 77 | this.startProbe(startPoint, endPoint) 78 | } 79 | 80 | // if we change content's transformY in a tick 81 | // such as: 0 -> 50px -> 0 82 | // transitionend will not be triggered 83 | // so we forceupdate by reflow 84 | if (!time) { 85 | this._reflow = this.content.offsetHeight 86 | if (isRealtimeProbeType) { 87 | this.hooks.trigger(this.hooks.eventTypes.move, endPoint) 88 | } 89 | this.hooks.trigger(this.hooks.eventTypes.end, endPoint) 90 | } 91 | } 92 | 93 | doStop(): boolean { 94 | const pending = this.pending 95 | this.setForceStopped(false) 96 | this.setCallStop(false) 97 | // still in transition 98 | if (pending) { 99 | this.setPending(false) 100 | cancelAnimationFrame(this.timer) 101 | const { x, y } = this.translater.getComputedPosition() 102 | 103 | this.transitionTime() 104 | this.translate({ x, y }) 105 | this.setForceStopped(true) 106 | this.setCallStop(true) 107 | this.hooks.trigger(this.hooks.eventTypes.forceStop, { x, y }) 108 | } 109 | return pending 110 | } 111 | 112 | stop() { 113 | const stopFromTransition = this.doStop() 114 | if (stopFromTransition) { 115 | this.hooks.trigger(this.hooks.eventTypes.callStop) 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /modules/actionSheet.nvue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 110 | 111 | 153 | -------------------------------------------------------------------------------- /android/com/itstudy/io/GetText.java: -------------------------------------------------------------------------------- 1 | package com.itstudy.io; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * @Title: TestTranslate 7 | * @author: 何杰 e-mail: 734412450@qq.com 8 | * @date: 2020/8/26 16:45 9 | * @ClassName: GetText 10 | * @Description: 获取txt文本内容 11 | */ 12 | public class GetText { 13 | 14 | 15 | 16 | //判断编码格式方法 17 | private static String getFileCharset(File sourceFile) { 18 | String charset = "GBK"; 19 | byte[] first3Bytes = new byte[3]; 20 | try { 21 | boolean checked = false; 22 | BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile)); 23 | bis.mark(0); 24 | int read = bis.read(first3Bytes, 0, 3); 25 | //文件编码为 ANSI 26 | if (read == -1) { 27 | return charset; 28 | } else if (first3Bytes[0] == (byte) 0xFF 29 | && first3Bytes[1] == (byte) 0xFE) { 30 | //文件编码为 Unicode 31 | charset = "UTF-16LE"; 32 | checked = true; 33 | } else if (first3Bytes[0] == (byte) 0xFE 34 | && first3Bytes[1] == (byte) 0xFF) { 35 | //文件编码为 Unicode big endian 36 | charset = "UTF-16BE"; 37 | checked = true; 38 | } else if (first3Bytes[0] == (byte) 0xEF 39 | && first3Bytes[1] == (byte) 0xBB 40 | && first3Bytes[2] == (byte) 0xBF) { 41 | //文件编码为 UTF-8 42 | charset = "UTF-8"; 43 | checked = true; 44 | } 45 | bis.reset(); 46 | if (!checked) { 47 | int loc = 0; 48 | while ((read = bis.read()) != -1) { 49 | loc++; 50 | if (read >= 0xF0) { 51 | break; 52 | } 53 | // 单独出现BF以下的,也算是GBK 54 | if (0x80 <= read && read <= 0xBF) { 55 | break; 56 | } 57 | if (0xC0 <= read && read <= 0xDF) { 58 | read = bis.read(); 59 | // 双字节 (0xC0 - 0xDF) 60 | if (0x80 <= read && read <= 0xBF) 61 | // (0x80 62 | // - 0xBF),也可能在GB编码内 63 | { 64 | continue; 65 | } else { 66 | break; 67 | } 68 | // 也有可能出错,但是几率较小 69 | } else if (0xE0 <= read && read <= 0xEF) { 70 | read = bis.read(); 71 | if (0x80 <= read && read <= 0xBF) { 72 | read = bis.read(); 73 | if (0x80 <= read && read <= 0xBF) { 74 | charset = "UTF-8"; 75 | break; 76 | } else{ 77 | break;} 78 | } else { 79 | break; 80 | } 81 | } 82 | } 83 | } 84 | bis.close(); 85 | } catch (Exception e) { 86 | e.printStackTrace(); 87 | } 88 | return charset; 89 | } 90 | 91 | public String getTextFromText(String filePath) { 92 | 93 | try { 94 | // 获取输入流 95 | InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), getFileCharset(new File(filePath))); 96 | BufferedReader br = new BufferedReader(isr); 97 | 98 | StringBuffer sb = new StringBuffer(); 99 | String temp = null; 100 | while ((temp = br.readLine()) != null) { 101 | sb.append(temp+"\r\n"); 102 | } 103 | br.close(); 104 | return sb.toString(); 105 | } catch (FileNotFoundException e) { 106 | // TODO Auto-generated catch block 107 | e.printStackTrace(); 108 | 109 | } catch (IOException e) { 110 | // TODO Auto-generated catch block 111 | e.printStackTrace(); 112 | } 113 | return null; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /pages.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages 3 | { 4 | "path": "pages/index/index" 5 | }, 6 | //本地小说添加页 7 | { 8 | "path": "pages/book/search/index" 9 | }, 10 | //在线小说添加页 11 | { 12 | "path": "pages/book/online/index" 13 | }, 14 | //小说详情页 15 | { 16 | "path": "pages/book/detail/index" 17 | }, 18 | //小说阅读页 19 | { 20 | "path": "pages/book/read/index", 21 | "style": { 22 | "disableScroll": false, 23 | "app-plus": { 24 | "bounce":"none" 25 | } 26 | } 27 | }, 28 | //小说设置页 29 | { 30 | "path": "pages/book/setting/index", 31 | "style": { 32 | "backgroundColor": "transparent", 33 | "app-plus": { 34 | "bounce":"none", 35 | "animationType": "fade-in", 36 | "background": "transparent", // 背景透明 37 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 38 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 39 | } 40 | } 41 | }, 42 | //本地漫画添加页 43 | { 44 | "path": "pages/comic/search/index" 45 | }, 46 | //在线漫画添加页 47 | { 48 | "path": "pages/comic/online/index" 49 | }, 50 | //漫画详情页 51 | { 52 | "path": "pages/comic/detail/index" 53 | }, 54 | //漫画阅读页 55 | { 56 | "path": "pages/comic/read/index" 57 | }, 58 | //设置页 59 | { 60 | "path": "pages/setting/index" 61 | }, 62 | //关于软件 63 | { 64 | "path": "pages/about/index" 65 | }, 66 | //音乐播放页面 67 | { 68 | "path": "pages/music/player", 69 | "style": { 70 | "backgroundColor": "transparent" 71 | } 72 | }, 73 | //音乐播放列表 74 | { 75 | "path": "pages/music/index", 76 | "style": { 77 | "backgroundColor": "transparent", 78 | "app-plus": { 79 | "bounce":"none", 80 | "animationType": "fade-in", 81 | "background": "transparent", // 背景透明 82 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 83 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 84 | } 85 | } 86 | }, 87 | //添加音乐 88 | { 89 | "path": "pages/music/search" 90 | }, 91 | //添加在线音乐 92 | { 93 | "path": "pages/music/online" 94 | }, 95 | //确认弹窗 96 | { 97 | "path": "modules/confirm", 98 | "style": { 99 | "backgroundColor": "transparent", 100 | "app-plus": { 101 | "bounce":"none", 102 | "animationType": "fade-in", 103 | "background": "transparent", // 背景透明 104 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 105 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 106 | } 107 | } 108 | }, 109 | //选择对话框 110 | { 111 | "path": "modules/actionSheet", 112 | "style": { 113 | "backgroundColor": "transparent", 114 | "app-plus": { 115 | "bounce":"none", 116 | "animationType": "fade-in", 117 | "background": "transparent", // 背景透明 118 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 119 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 120 | } 121 | } 122 | }, 123 | //文本编辑框 124 | { 125 | "path": "modules/edit", 126 | "style": { 127 | "backgroundColor": "transparent", 128 | "app-plus": { 129 | "bounce":"none", 130 | "animationType": "fade-in", 131 | "background": "transparent", // 背景透明 132 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 133 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 134 | } 135 | } 136 | }, 137 | //章节书签展示页 138 | { 139 | "path": "modules/catalog", 140 | "style": { 141 | "backgroundColor": "transparent", 142 | "app-plus": { 143 | "bounce":"none", 144 | "animationType": "fade-in", 145 | "background": "transparent", // 背景透明 146 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 147 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 148 | } 149 | } 150 | }, 151 | //安全密码 152 | { 153 | "path": "modules/security", 154 | "style": { 155 | "backgroundColor": "transparent", 156 | "app-plus": { 157 | "bounce":"none", 158 | "animationType": "fade-in", 159 | "background": "transparent", // 背景透明 160 | "backgroundColor": "rgba(0,0,0,0)", // 背景透明 161 | "popGesture": "none" // 关闭IOS屏幕左边滑动关闭当前页面的功能 162 | } 163 | } 164 | } 165 | ], 166 | "globalStyle": { 167 | "disableScroll": true, // 不嵌套 scroller 168 | "navigationStyle": "custom", 169 | "navigationBarTextStyle": "white", 170 | "navigationBarBackgroundColor": "transparent", 171 | "app-plus": { 172 | "titleNView": false 173 | } 174 | }, 175 | "condition" : { //模式配置,仅开发期间生效 176 | "current": 0, //当前激活的模式(list 的索引项) 177 | "list": [ 178 | { 179 | "name": "", //模式名称 180 | "path": "", //启动页面,必选 181 | "query": "" //启动参数,在页面的onLoad函数里面得到 182 | } 183 | ] 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /modules/confirm.nvue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 108 | 109 | 179 | -------------------------------------------------------------------------------- /modules/edit.nvue: -------------------------------------------------------------------------------- 1 |