airdcpp-webui 2.14.0-beta.11 → 2.14.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.html +1 -1
- package/dist/js/{544.65aa9935aff661f699f2.chunk.js → 544.23c1c02472b86725dbe7.chunk.js} +2 -2
- package/dist/js/544.23c1c02472b86725dbe7.chunk.js.gz +0 -0
- package/dist/js/{544.65aa9935aff661f699f2.chunk.js.map → 544.23c1c02472b86725dbe7.chunk.js.map} +1 -1
- package/dist/js/{550.83271f41ad0cccc6815b.chunk.js → 550.43735d298b0c3e70c6bd.chunk.js} +2 -2
- package/dist/js/550.43735d298b0c3e70c6bd.chunk.js.gz +0 -0
- package/dist/js/{550.83271f41ad0cccc6815b.chunk.js.map → 550.43735d298b0c3e70c6bd.chunk.js.map} +1 -1
- package/dist/js/926.c344692db21ff4746b0d.chunk.js +2 -0
- package/dist/js/926.c344692db21ff4746b0d.chunk.js.gz +0 -0
- package/dist/js/926.c344692db21ff4746b0d.chunk.js.map +1 -0
- package/dist/js/{944.890172ae3c849dfa9e12.chunk.js → 944.31cf601418cceee63aa8.chunk.js} +2 -2
- package/dist/js/944.31cf601418cceee63aa8.chunk.js.gz +0 -0
- package/dist/js/944.31cf601418cceee63aa8.chunk.js.map +1 -0
- package/dist/js/{favorite-hubs.10f837eb1b9982c252aa.chunk.js → favorite-hubs.295f583c2e1befcbbbbb.chunk.js} +2 -2
- package/dist/js/favorite-hubs.295f583c2e1befcbbbbb.chunk.js.gz +0 -0
- package/dist/js/{favorite-hubs.10f837eb1b9982c252aa.chunk.js.map → favorite-hubs.295f583c2e1befcbbbbb.chunk.js.map} +1 -1
- package/dist/js/{filelists.8fe983ba06c08a5c65c2.chunk.js → filelists.f098fc396efc445ef837.chunk.js} +2 -2
- package/dist/js/filelists.f098fc396efc445ef837.chunk.js.gz +0 -0
- package/dist/js/{filelists.8fe983ba06c08a5c65c2.chunk.js.map → filelists.f098fc396efc445ef837.chunk.js.map} +1 -1
- package/dist/js/{files.168b9574438986003ddd.chunk.js → files.64f72b3869667e0d4c7e.chunk.js} +2 -2
- package/dist/js/files.64f72b3869667e0d4c7e.chunk.js.gz +0 -0
- package/dist/js/{files.168b9574438986003ddd.chunk.js.map → files.64f72b3869667e0d4c7e.chunk.js.map} +1 -1
- package/dist/js/{home.2fac0aaf4db41cf0a314.chunk.js → home.e0421a3f337897e900d5.chunk.js} +3 -3
- package/dist/js/home.e0421a3f337897e900d5.chunk.js.gz +0 -0
- package/dist/js/{home.2fac0aaf4db41cf0a314.chunk.js.map → home.e0421a3f337897e900d5.chunk.js.map} +1 -1
- package/dist/js/{hubs.43ca34eee0ef61fc32b2.chunk.js → hubs.82f0f581d104a03d4461.chunk.js} +2 -2
- package/dist/js/hubs.82f0f581d104a03d4461.chunk.js.gz +0 -0
- package/dist/js/{hubs.43ca34eee0ef61fc32b2.chunk.js.map → hubs.82f0f581d104a03d4461.chunk.js.map} +1 -1
- package/dist/js/main.eea930701ff0165c262c.entry.js +3 -0
- package/dist/js/{main.cacce80f03c18d3bf7d9.entry.js.LICENSE.txt → main.eea930701ff0165c262c.entry.js.LICENSE.txt} +1 -1
- package/dist/js/main.eea930701ff0165c262c.entry.js.gz +0 -0
- package/dist/js/{main.cacce80f03c18d3bf7d9.entry.js.map → main.eea930701ff0165c262c.entry.js.map} +1 -1
- package/dist/js/queue.2e2c51447eed5f81354d.chunk.js +2 -0
- package/dist/js/queue.2e2c51447eed5f81354d.chunk.js.gz +0 -0
- package/dist/js/queue.2e2c51447eed5f81354d.chunk.js.map +1 -0
- package/dist/js/{search.54d77ceed2d7b5286e96.chunk.js → search.52d677e31d86ea727809.chunk.js} +2 -2
- package/dist/js/search.52d677e31d86ea727809.chunk.js.gz +0 -0
- package/dist/js/{search.54d77ceed2d7b5286e96.chunk.js.map → search.52d677e31d86ea727809.chunk.js.map} +1 -1
- package/dist/js/{settings.e2c30f0541c9eaaa8741.chunk.js → settings.064c3f5ee2ec8c698a4c.chunk.js} +2 -2
- package/dist/js/settings.064c3f5ee2ec8c698a4c.chunk.js.gz +0 -0
- package/dist/js/settings.064c3f5ee2ec8c698a4c.chunk.js.map +1 -0
- package/dist/sw.js +1 -1
- package/dist/sw.js.gz +0 -0
- package/dist/sw.js.map +1 -1
- package/package.json +1 -1
- package/dist/js/544.65aa9935aff661f699f2.chunk.js.gz +0 -0
- package/dist/js/550.83271f41ad0cccc6815b.chunk.js.gz +0 -0
- package/dist/js/926.ddc01ea089c248c6a6dd.chunk.js +0 -2
- package/dist/js/926.ddc01ea089c248c6a6dd.chunk.js.gz +0 -0
- package/dist/js/926.ddc01ea089c248c6a6dd.chunk.js.map +0 -1
- package/dist/js/944.890172ae3c849dfa9e12.chunk.js.gz +0 -0
- package/dist/js/944.890172ae3c849dfa9e12.chunk.js.map +0 -1
- package/dist/js/favorite-hubs.10f837eb1b9982c252aa.chunk.js.gz +0 -0
- package/dist/js/filelists.8fe983ba06c08a5c65c2.chunk.js.gz +0 -0
- package/dist/js/files.168b9574438986003ddd.chunk.js.gz +0 -0
- package/dist/js/home.2fac0aaf4db41cf0a314.chunk.js.gz +0 -0
- package/dist/js/hubs.43ca34eee0ef61fc32b2.chunk.js.gz +0 -0
- package/dist/js/locales/zh_CN-GB2312-webui-main-json.c56c6d389b7951c4f74d.chunk.js +0 -1
- package/dist/js/locales/zh_CN-GB2312-webui-main-json.c56c6d389b7951c4f74d.chunk.js.gz +0 -0
- package/dist/js/main.cacce80f03c18d3bf7d9.entry.js +0 -3
- package/dist/js/main.cacce80f03c18d3bf7d9.entry.js.gz +0 -0
- package/dist/js/queue.6ff3192c939acd0170e7.chunk.js +0 -2
- package/dist/js/queue.6ff3192c939acd0170e7.chunk.js.gz +0 -0
- package/dist/js/queue.6ff3192c939acd0170e7.chunk.js.map +0 -1
- package/dist/js/search.54d77ceed2d7b5286e96.chunk.js.gz +0 -0
- package/dist/js/settings.e2c30f0541c9eaaa8741.chunk.js.gz +0 -0
- package/dist/js/settings.e2c30f0541c9eaaa8741.chunk.js.map +0 -1
- /package/dist/js/{home.2fac0aaf4db41cf0a314.chunk.js.LICENSE.txt → home.e0421a3f337897e900d5.chunk.js.LICENSE.txt} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js/filelists.8fe983ba06c08a5c65c2.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/utils/ShareProfileUtils.ts","webpack://airdcpp-webui/./src/routes/Sidebar/decorators/UserItemHandlerDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/ShareProfileSelector.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistNew.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/item-info-dialog/FilelistItemInfoDialog.tsx","webpack://airdcpp-webui/./src/stores/views/FilelistViewStore.js","webpack://airdcpp-webui/./src/actions/ui/filelist/FilelistItemActions.ts","webpack://airdcpp-webui/./src/actions/ui/filelist/FilelistSessionActions.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistItemTable.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/ListBrowser.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/effects/useSyncFilelistLocation.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistSession.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/style.css?8d81","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/Filelists.tsx","webpack://airdcpp-webui/./src/components/file-item-info/style.css","webpack://airdcpp-webui/./src/services/api/ShareApi.ts","webpack://airdcpp-webui/./src/routes/Sidebar/components/RecentLayout.tsx","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/services/HttpService.ts","webpack://airdcpp-webui/./src/components/file-item-info/style.css?a322","webpack://airdcpp-webui/./src/components/file-item-info/FileItemInfoGrid.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/style.css"],"sourcesContent":["import ShareProfileConstants from '@/constants/ShareProfileConstants';\r\n\r\nimport { Formatter } from '@/context/FormatterContext';\r\n\r\nimport * as API from '@/types/api';\r\n\r\nexport const formatProfileNameWithSize = (\r\n profile: API.ShareProfile,\r\n { formatSize }: Formatter,\r\n) => {\r\n let str = profile.str;\r\n if (profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size)})`;\r\n }\r\n\r\n return str;\r\n};\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile, formatter: Formatter) => {\r\n return {\r\n id: profile.id,\r\n name: formatProfileNameWithSize(profile, formatter),\r\n };\r\n};\r\n","import { userOnlineStatusToColor } from '@/utils/TypeConvert';\r\nimport { UserMenu } from '@/components/action-menu';\r\nimport UserIcon from '@/components/icon/UserIcon';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\ninterface UserSessionBase {\r\n user: API.HintedUser;\r\n}\r\n\r\nexport default function <SessionT extends UI.SessionItemBase & UserSessionBase>(\r\n itemMenuIds: string[],\r\n) {\r\n const UserItemHandlerDecorator: UI.SessionInfoGetter<SessionT> = {\r\n itemNameGetter(session) {\r\n return session.user.nicks;\r\n },\r\n\r\n itemStatusGetter(session) {\r\n const { flags } = session.user;\r\n return userOnlineStatusToColor(flags);\r\n },\r\n\r\n itemHeaderDescriptionGetter(session) {\r\n return session.user.hub_names;\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return <UserIcon flags={session.user.flags} />;\r\n },\r\n\r\n itemHeaderTitleGetter(session, location, actionMenu) {\r\n const { user } = session;\r\n return (\r\n <UserMenu user={user} ids={itemMenuIds} remoteMenuId={MenuConstants.HINTED_USER}>\r\n {actionMenu}\r\n </UserMenu>\r\n );\r\n },\r\n };\r\n\r\n return UserItemHandlerDecorator;\r\n}\r\n","import Dropdown from '@/components/semantic/Dropdown';\nimport MenuItemLink from '@/components/semantic/MenuItemLink';\n\nimport ShareProfileDecorator, {\n ShareProfileDecoratorChildProps,\n} from '@/decorators/ShareProfileDecorator';\n\nimport * as API from '@/types/api';\nimport * as UI from '@/types/ui';\n\nimport { formatProfileNameWithSize } from '@/utils/ShareProfileUtils';\nimport { useFormatter } from '@/context/FormatterContext';\n\ninterface ShareProfileSelectorProps {\n // Callback after selecting a profile\n onProfileChanged: (profileId: number) => void;\n\n sessionT: UI.ModuleTranslator;\n}\n\nconst ShareProfileSelector: React.FC<\n ShareProfileSelectorProps & ShareProfileDecoratorChildProps\n> = ({ sessionT, profiles, onProfileChanged }) => {\n const formatter = useFormatter();\n\n const getDropdownItem = (profile: API.ShareProfile) => {\n return (\n <MenuItemLink key={profile.id} onClick={() => onProfileChanged(profile.id)}>\n {formatProfileNameWithSize(profile, formatter)}\n </MenuItemLink>\n );\n };\n\n return (\n <Dropdown\n className=\"profile top right pointing\"\n caption={sessionT.translate('Browse own share...')}\n triggerIcon=\"\"\n >\n {profiles.map(getDropdownItem)}\n </Dropdown>\n );\n};\n\nexport default ShareProfileDecorator(ShareProfileSelector, false);\n","import RecentLayout from '@/routes/Sidebar/components/RecentLayout';\r\n\r\nimport ShareProfileSelector from '@/routes/Sidebar/routes/Filelists/components/ShareProfileSelector';\r\nimport { HistoryEntryEnum } from '@/constants/HistoryConstants';\r\n\r\nimport * as API from '@/types/api';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport { UserSelectField } from '@/components/select';\r\nimport { NewSessionLayoutProps } from '@/routes/Sidebar/components/types';\r\nimport LinkButton from '@/components/semantic/LinkButton';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { useSessionStore } from '@/context/SessionStoreContext';\r\nimport { useSocket } from '@/context/SocketContext';\r\nimport { useSession } from '@/context/AppStoreContext';\r\n\r\nconst FilelistNew: React.FC<NewSessionLayoutProps> = ({ navigate, sessionT }) => {\r\n const sessionStore = useSessionStore();\r\n const socket = useSocket();\r\n const session = useSession();\r\n\r\n const createSessionProps = {\r\n sessionStore,\r\n socket,\r\n navigate,\r\n t: sessionT.plainT,\r\n };\r\n\r\n const handleSubmit = (user: API.HintedUser) => {\r\n FilelistAPIActions.createRemoteSession({ user }, createSessionProps);\r\n };\r\n\r\n const onProfileChanged = (shareProfileId: number) => {\r\n FilelistAPIActions.initCreateLocalSession(session)(\r\n { shareProfileId },\r\n createSessionProps,\r\n );\r\n };\r\n\r\n const recentUserRender = (entry: API.HistoryItem) => {\r\n const caption =\r\n entry.user!.nicks + (entry.description ? ` (${entry.description})` : '');\r\n return <LinkButton onClick={(_) => handleSubmit(entry.user!)} caption={caption} />;\r\n };\r\n\r\n const hasSession = (entry: API.HistoryItem) => {\r\n return !!sessionStore.filelists.getSession(entry.user!.cid);\r\n };\r\n\r\n return (\r\n <div className=\"filelist session new\">\r\n <UserSelectField\r\n onChange={handleSubmit}\r\n offlineMessage={sessionT.t(\r\n 'offlineMessage',\r\n 'You must to be connected to at least one hub in order to download filelists from other users',\r\n )}\r\n isClearable={false}\r\n autoFocus={true}\r\n />\r\n <ShareProfileSelector onProfileChanged={onProfileChanged} sessionT={sessionT} />\r\n <RecentLayout\r\n entryType={HistoryEntryEnum.FILELIST}\r\n hasSession={hasSession}\r\n entryTitleRenderer={recentUserRender}\r\n entryIcon={IconConstants.FILELISTS_PLAIN}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FilelistNew;\r\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from '@/context/FormatterContext';\r\nimport { FooterItem, SessionFooter } from '@/routes/Sidebar/components/SessionFooter';\r\nimport { usingMobileLayout } from '@/utils/BrowserUtils';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\ninterface FilelistFooterProps {\r\n filelist: API.FilelistSession;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FilelistFooter: React.FC<FilelistFooterProps> = ({ filelist, sessionT }) => {\r\n const { formatSize } = useFormatter();\r\n if (usingMobileLayout()) {\r\n return null;\r\n }\r\n\r\n let locationText = filelist.location!.type.str;\r\n if (locationText.length > 0) {\r\n locationText = `${formatSize(filelist.location!.size)} (${locationText})`;\r\n }\r\n\r\n return (\r\n <SessionFooter>\r\n <FooterItem label={sessionT.translate('Directory size')} text={locationText} />\r\n <FooterItem\r\n label={sessionT.translate('Total list size')}\r\n text={formatSize(filelist.total_size)}\r\n />\r\n </SessionFooter>\r\n );\r\n};\r\n\r\nexport default FilelistFooter;\r\n","import { Component } from 'react';\r\nimport RouteModal from '@/components/semantic/RouteModal';\r\n\r\nimport FileIcon from '@/components/icon/FileIcon';\r\n\r\nimport DownloadDialog from '@/components/download/DownloadDialog';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from '@/decorators/ModalRouteDecorator';\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from '@/decorators/DataProviderDecorator';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FileItemInfoGrid } from '@/components/file-item-info';\r\nimport FilelistConstants from '@/constants/FilelistConstants';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\n\r\ninterface FilelistItemInfoDialogProps {\r\n filelist: API.FilelistSession;\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n fileItem: API.FilelistItem;\r\n}\r\n\r\ntype Props = FilelistItemInfoDialogProps & ModalRouteDecoratorChildProps;\r\n\r\nexport const FilelistItemGetter = (filelist: API.FilelistSession) => {\r\n const ret: UI.DownloadItemDataGetter<API.FilelistItem> = (itemId, socket) => {\r\n return socket.get(`${FilelistConstants.MODULE_URL}/${filelist.id}/items/${itemId}`);\r\n };\r\n\r\n return ret;\r\n};\r\n\r\nclass FilelistItemInfoDialog extends Component<Props & DataProps> {\r\n static readonly displayName = 'FilelistItemInfoDialog';\r\n\r\n render() {\r\n const { fileItem, filelist } = this.props;\r\n return (\r\n <RouteModal\r\n className=\"filelist-item\"\r\n title={fileItem.name}\r\n closable={true}\r\n icon={<FileIcon typeInfo={fileItem.type} />}\r\n fullHeight={true}\r\n {...this.props}\r\n >\r\n <DownloadDialog\r\n downloadHandler={filelistDownloadHandler}\r\n itemDataGetter={FilelistItemGetter(filelist)}\r\n userGetter={() => filelist.user}\r\n sessionItem={filelist}\r\n />\r\n <FileItemInfoGrid\r\n fileItem={fileItem}\r\n downloadHandler={filelistDownloadHandler}\r\n user={filelist.user}\r\n sessionItem={filelist}\r\n />\r\n </RouteModal>\r\n );\r\n }\r\n}\r\n\r\nconst Decorated = ModalRouteDecorator<FilelistItemInfoDialogProps>(\r\n DataProviderDecorator<Props, DataProps>(FilelistItemInfoDialog, {\r\n urls: {\r\n fileItem: ({ params, filelist }, socket) =>\r\n FilelistItemGetter(filelist)(params.itemId!, socket),\r\n },\r\n }),\r\n 'item/:itemId',\r\n);\r\n\r\nexport { Decorated as FilelistItemInfoDialog };\r\n","import ViewStoreMixin from '@/mixins/ViewStoreMixin';\nimport Reflux from 'reflux';\nimport FilelistConstants from '@/constants/FilelistConstants';\n// import FilelistSessionStore from '../reflux/FilelistSessionStore.ts.tmp';\n\nexport default Reflux.createStore({\n _viewName: `${FilelistConstants.VIEW_ID}_view`,\n _apiUrl: FilelistConstants.SESSIONS_URL,\n // _sessionStore: FilelistSessionStore,\n mixins: [ViewStoreMixin('name')],\n});\n","import FilelistConstants from '@/constants/FilelistConstants';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { refreshVirtual } from '@/services/api/ShareApi';\r\n\r\ntype Filter = UI.ActionFilter<API.FilelistItem, API.FilelistSession>;\r\n\r\n// Filters\r\nconst isMe: Filter = ({ entity }) => entity.user.flags.includes('self');\r\nconst isRoot: Filter = ({ itemData }) => itemData.path === '/';\r\nconst isPartialList: Filter = ({ entity }) => entity.partial_list;\r\nconst isDirectory: Filter = ({ itemData }) => itemData.type.id === 'directory';\r\n\r\nconst filterReload: Filter = (data) => isPartialList(data) && isDirectory(data);\r\nconst filterDetails: Filter = (data) => !isRoot(data);\r\n\r\n// Handlers\r\ntype Handler = UI.ActionHandler<API.FilelistItem, API.FilelistSession>;\r\n\r\nconst handleReloadDirectory: Handler = ({ itemData: item, entity: session, socket }) => {\r\n return socket.post(`${FilelistConstants.SESSIONS_URL}/${session.id}/directory`, {\r\n list_path: item.path,\r\n reload: true,\r\n });\r\n};\r\n\r\nconst handleRefreshShare: Handler = ({ itemData, socket }) => {\r\n return refreshVirtual(itemData.path, socket);\r\n};\r\n\r\nconst handleItemDetails: Handler = ({ itemData, navigate }) => {\r\n navigate(`item/${itemData.id}`);\r\n};\r\n\r\n// Actions\r\nexport const FilelistItemReloadDirectoryAction = {\r\n id: 'reloadDirectory',\r\n displayName: 'Reload',\r\n access: API.AccessEnum.FILELISTS_VIEW,\r\n icon: IconConstants.RELOAD,\r\n filter: filterReload,\r\n handler: handleReloadDirectory,\r\n};\r\n\r\nexport const FilelistItemRefreshShareAction = {\r\n id: 'refreshShare',\r\n displayName: 'Refresh in share',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REFRESH_COLORED,\r\n filter: isMe,\r\n handler: handleRefreshShare,\r\n};\r\n\r\nexport const FilelistItemDetailsAction = {\r\n id: 'details',\r\n displayName: 'Details',\r\n icon: IconConstants.DETAILS,\r\n handler: handleItemDetails,\r\n filter: filterDetails,\r\n};\r\n\r\nconst FilelistItemActions: UI.ActionListType<API.FilelistItem, API.FilelistSession> = {\r\n reloadDirectory: FilelistItemReloadDirectoryAction,\r\n refreshShare: FilelistItemRefreshShareAction,\r\n details: FilelistItemDetailsAction,\r\n};\r\n\r\nexport const FilelistItemActionModule = {\r\n moduleId: UI.Modules.FILELISTS,\r\n subId: 'item',\r\n};\r\n\r\nexport const FilelistItemActionMenu = {\r\n moduleData: FilelistItemActionModule,\r\n actions: FilelistItemActions,\r\n};\r\n","import FilelistConstants from '@/constants/FilelistConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { BuildRemoveSessionAction } from '../decorators/SessionActionDecorator';\r\n\r\nconst FilelistRemoveAction = BuildRemoveSessionAction(\r\n FilelistConstants.SESSIONS_URL,\r\n API.AccessEnum.FILELISTS_EDIT,\r\n);\r\n\r\nconst FilelistSessionActions: UI.ActionListType<API.FilelistSession> = {\r\n remove: FilelistRemoveAction,\r\n};\r\n\r\nexport const FilelistSessionActionModule = {\r\n moduleId: UI.Modules.FILELISTS,\r\n};\r\n\r\nexport const FilelistSessionActionMenu = {\r\n moduleData: FilelistSessionActionModule,\r\n actions: FilelistSessionActions,\r\n};\r\n","import * as React from 'react';\r\n\r\nimport { dupeToStringType } from '@/utils/TypeConvert';\r\nimport { TableActionMenu } from '@/components/action-menu';\r\n\r\nimport FilelistViewStore from '@/stores/views/FilelistViewStore';\r\n\r\nimport VirtualTable from '@/components/table/VirtualTable';\r\nimport {\r\n SizeCell,\r\n DurationCell,\r\n FileDownloadCell,\r\n FileDownloadCellCaptionGetter,\r\n} from '@/components/table/Cell';\r\nimport { Column } from 'fixed-data-table-2';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FilelistItemInfoDialog } from './item-info-dialog';\r\nimport { RowWrapperCellChildProps } from '@/components/table/RowWrapperCell';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\nimport { FilelistItemActionMenu } from '@/actions/ui/filelist';\r\nimport { useSessionStore } from '@/context/SessionStoreContext';\r\nimport LinkButton from '@/components/semantic/LinkButton';\r\n\r\ninterface NameCellProps extends RowWrapperCellChildProps<string, API.FilelistItem> {\r\n filelist: API.FilelistSession;\r\n captionGetter: FileDownloadCellCaptionGetter;\r\n}\r\n\r\nconst NameCell: React.FC<NameCellProps> = ({\r\n rowDataGetter,\r\n captionGetter,\r\n filelist,\r\n ...other\r\n}) => {\r\n return (\r\n <FileDownloadCell\r\n userGetter={() => filelist.user}\r\n downloadHandler={filelistDownloadHandler}\r\n rowDataGetter={rowDataGetter}\r\n entity={filelist}\r\n remoteMenuId={MenuConstants.FILELIST_ITEM}\r\n captionGetter={captionGetter}\r\n {...other}\r\n >\r\n <TableActionMenu\r\n actions={FilelistItemActionMenu}\r\n itemData={rowDataGetter}\r\n ids={['refreshShare', 'details']}\r\n entity={filelist}\r\n />\r\n </FileDownloadCell>\r\n );\r\n};\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n onClickDirectory: (path: string) => void;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FilelistItemTable: React.FC<ListBrowserProps> = ({\r\n filelist,\r\n sessionT,\r\n onClickDirectory,\r\n ...other\r\n}) => {\r\n const rowClassNameGetter = (rowData: API.FilelistItem) => {\r\n // Don't highlight dupes in own filelist...\r\n const isOwnList = filelist.user.flags.includes('self');\r\n return isOwnList ? '' : dupeToStringType(rowData.dupe);\r\n };\r\n\r\n const emptyRowsNodeGetter = () => {\r\n const { location, state } = filelist;\r\n const { translate } = sessionT;\r\n\r\n if (state.id === 'download_failed') {\r\n return (\r\n <Message\r\n icon={IconConstants.ERROR}\r\n title={translate('Download failed')}\r\n description={state.str}\r\n />\r\n );\r\n }\r\n\r\n // The list finished downloading but the view hasn't updated yet\r\n const { files, directories } = location!.type as API.DirectoryType;\r\n if (files !== 0 || directories !== 0) {\r\n return <Loader text={translate('Updating view')} />;\r\n }\r\n\r\n // The directory was changed but the download state hasn't changed yet\r\n if (!location!.complete) {\r\n return <Loader text={translate('Preparing download')} />;\r\n }\r\n\r\n return (\r\n <Message\r\n title={translate('No content to display')}\r\n description={translate('The directory is empty')}\r\n />\r\n );\r\n };\r\n\r\n const getCellCaption: FileDownloadCellCaptionGetter = (cellData, rowDataGetter) => {\r\n if (rowDataGetter().type.id === 'directory') {\r\n const onClick = () => onClickDirectory(filelist.location!.path + cellData + '/');\r\n return <LinkButton caption={cellData} onClick={onClick} />;\r\n }\r\n\r\n return cellData;\r\n };\r\n\r\n // const { session } = this.props;\r\n const sessionStore = useSessionStore();\r\n return (\r\n <>\r\n <VirtualTable\r\n emptyRowsNodeGetter={emptyRowsNodeGetter}\r\n rowClassNameGetter={rowClassNameGetter}\r\n store={FilelistViewStore}\r\n entityId={filelist.id}\r\n viewId={filelist.location!.path}\r\n sessionStore={sessionStore.filelists}\r\n moduleId={UI.Modules.FILELISTS}\r\n textFilterProps={{\r\n autoFocus: true,\r\n }}\r\n >\r\n <Column\r\n name=\"Name\"\r\n width={200}\r\n columnKey=\"name\"\r\n cell={<NameCell captionGetter={getCellCaption} filelist={filelist} />}\r\n flexGrow={8}\r\n />\r\n <Column\r\n name=\"Size\"\r\n width={60}\r\n columnKey=\"size\"\r\n cell={<SizeCell />}\r\n flexGrow={1}\r\n />\r\n <Column name=\"Type\" width={70} columnKey=\"type\" flexGrow={1} hideWidth={500} />\r\n <Column\r\n name=\"Last modified\"\r\n width={80}\r\n columnKey=\"time\"\r\n cell={<DurationCell />}\r\n flexGrow={1}\r\n />\r\n </VirtualTable>\r\n <FilelistItemInfoDialog filelist={filelist} />\r\n </>\r\n );\r\n};\r\n\r\nexport default FilelistItemTable;\r\n","import * as React from 'react';\r\n\r\nimport BrowserBar from '@/components/browserbar/BrowserBar';\r\nimport { ActionMenu, DownloadMenu } from '@/components/action-menu';\r\n\r\nimport DownloadDialog from '@/components/download/DownloadDialog';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FilelistItemGetter } from './item-info-dialog';\r\nimport FilelistItemTable from './FilelistItemTable';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\nimport { Location, useBlocker } from 'react-router';\r\nimport { useSyncFilelistLocation } from '../effects/useSyncFilelistLocation';\r\nimport NotificationActions from '@/actions/NotificationActions';\r\nimport { FilelistItemActionMenu } from '@/actions/ui/filelist';\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n location: Location;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst ListBrowser: React.FC<ListBrowserProps> = (props) => {\r\n const { sessionT, filelist } = props;\r\n const [hasClickedDirectory, setHasClickedDirectory] = React.useState(false);\r\n\r\n const updateLocationState = useSyncFilelistLocation(props);\r\n\r\n const handleClickDirectory = (path: string) => {\r\n if (!hasClickedDirectory) {\r\n setHasClickedDirectory(true);\r\n }\r\n\r\n updateLocationState(path, false);\r\n };\r\n\r\n useBlocker(({ currentLocation, nextLocation, historyAction }) => {\r\n if (\r\n historyAction === 'POP' &&\r\n hasClickedDirectory &&\r\n nextLocation.pathname !== currentLocation.pathname\r\n ) {\r\n setHasClickedDirectory(false);\r\n NotificationActions.info({\r\n title: sessionT.t('confirmLeave', 'Confirm action'),\r\n message: sessionT.t(\r\n 'confirmLeaveDesc',\r\n 'Click the back button again to leave this filelist',\r\n ),\r\n });\r\n return true;\r\n }\r\n\r\n return false;\r\n });\r\n\r\n const getCurrentDirectory = () => {\r\n return filelist.location;\r\n };\r\n\r\n const selectedNameFormatter = (caption: React.ReactNode) => {\r\n return (\r\n <DownloadMenu\r\n caption={caption}\r\n user={filelist.user}\r\n itemInfoGetter={getCurrentDirectory}\r\n downloadHandler={filelistDownloadHandler}\r\n contextElement=\".session-container\"\r\n entity={filelist}\r\n remoteMenuId={MenuConstants.FILELIST_ITEM}\r\n >\r\n <ActionMenu\r\n itemData={filelist.location}\r\n actions={FilelistItemActionMenu}\r\n entity={filelist}\r\n />\r\n </DownloadMenu>\r\n );\r\n };\r\n\r\n const userGetter = () => {\r\n return filelist.user;\r\n };\r\n\r\n const filelistItemFetcher = FilelistItemGetter(filelist);\r\n\r\n return (\r\n <div className=\"browser\">\r\n <BrowserBar\r\n path={filelist.location!.path}\r\n separator=\"/\"\r\n rootPath=\"/\"\r\n rootName={sessionT.translate('Root')}\r\n itemClickHandler={handleClickDirectory}\r\n selectedNameFormatter={selectedNameFormatter}\r\n // Just to make sure that the bar gets re-rendered when the switching to a different session (due to dropdown)\r\n entityId={filelist.id}\r\n />\r\n <FilelistItemTable\r\n filelist={filelist}\r\n sessionT={sessionT}\r\n onClickDirectory={handleClickDirectory}\r\n />\r\n <DownloadDialog\r\n downloadHandler={filelistDownloadHandler}\r\n itemDataGetter={filelistItemFetcher}\r\n userGetter={userGetter}\r\n sessionItem={filelist}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default ListBrowser;\r\n","import * as React from 'react';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { changeFilelistDirectory } from '@/services/api/FilelistApi';\r\nimport { runBackgroundSocketAction } from '@/utils/ActionUtils';\r\nimport { Location, useNavigate } from 'react-router';\r\nimport { useSocket } from '@/context/SocketContext';\r\n\r\nexport type FilelistLocationState = { directory: string } | undefined;\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n location: Location;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\n// Keeps the current location in sync with the backend\r\nexport const useSyncFilelistLocation = ({\r\n filelist,\r\n location,\r\n sessionT,\r\n}: ListBrowserProps) => {\r\n const navigate = useNavigate();\r\n const socket = useSocket();\r\n\r\n const apiSendChangeDirectory = (directory: string) => {\r\n runBackgroundSocketAction(\r\n () => changeFilelistDirectory(filelist, directory, socket),\r\n sessionT.plainT,\r\n );\r\n };\r\n\r\n const updateLocationState = (directory: string, replace: boolean) => {\r\n const locationState = location.state as FilelistLocationState;\r\n if (directory === locationState?.directory) {\r\n return;\r\n }\r\n\r\n // Handle it through location state data\r\n // as we also handle history navigation changes\r\n const newState: FilelistLocationState = {\r\n directory,\r\n };\r\n\r\n navigate(location.pathname, {\r\n state: newState,\r\n replace,\r\n });\r\n };\r\n\r\n // Handler for directory changes received from the API\r\n React.useEffect(() => {\r\n const locationState = location.state as FilelistLocationState;\r\n\r\n if (!locationState) {\r\n // Initial mount\r\n updateLocationState(filelist.location!.path, true);\r\n return;\r\n }\r\n\r\n // Nothing has changed?\r\n if (locationState.directory === filelist.location!.path) {\r\n return;\r\n }\r\n\r\n // Change initiated by another session/GUI, update our location\r\n updateLocationState(filelist.location!.path, true);\r\n }, [filelist.location?.path]);\r\n\r\n // Handler for own changes\r\n React.useEffect(() => {\r\n const locationState = location.state as FilelistLocationState;\r\n if (!locationState) {\r\n // Initial mount, handled by the previous useEffect\r\n return;\r\n }\r\n\r\n const directory = locationState.directory;\r\n if (directory === filelist.location!.path) {\r\n return;\r\n }\r\n\r\n // It's our change\r\n if (directory) {\r\n apiSendChangeDirectory(directory);\r\n }\r\n }, [(location.state as FilelistLocationState)?.directory]);\r\n\r\n return updateLocationState;\r\n};\r\n","import FilelistFooter from '@/routes/Sidebar/routes/Filelists/components/FilelistFooter';\r\n\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport classNames from 'classnames';\r\nimport ListBrowser from './ListBrowser';\r\nimport { SessionChildProps } from '@/routes/Sidebar/components/types';\r\nimport { useActiveSession } from '@/effects/ActiveSessionEffect';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { FilelistStoreSelector } from '@/stores/session/filelistSlice';\r\n\r\ntype FilelistSessionProps = SessionChildProps<\r\n API.FilelistSession,\r\n UI.EmptyObject,\r\n UI.EmptyObject\r\n>;\r\n\r\nconst FilelistSession: React.FC<FilelistSessionProps> = ({\r\n sessionItem,\r\n sessionT,\r\n location: routerLocation,\r\n}) => {\r\n useActiveSession(sessionItem, FilelistAPIActions, FilelistStoreSelector);\r\n\r\n const { user, location: listLocation, state } = sessionItem;\r\n\r\n const isOwnList = user.flags.includes('self');\r\n const className = classNames('filelist session', { self: isOwnList });\r\n if (user.flags.includes('offline') && !isOwnList) {\r\n return (\r\n <div className={className}>\r\n <Message\r\n title={sessionT.t('userOffline', 'User offline')}\r\n description={sessionT.t(\r\n 'userOfflineDesc',\r\n 'You will be able to continue browsing when the user comes back online',\r\n )}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n if ((state.id !== 'loaded' && state.id !== 'download_failed') || !listLocation) {\r\n return (\r\n <div className={className}>\r\n <Loader text={state.str} />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className}>\r\n <ListBrowser location={routerLocation} filelist={sessionItem} sessionT={sessionT} />\r\n\r\n <FilelistFooter filelist={sessionItem} sessionT={sessionT} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FilelistSession;\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport SessionLayout from '@/routes/Sidebar/components/SessionLayout';\r\nimport UserItemHandlerDecorator from '@/routes/Sidebar/decorators/UserItemHandlerDecorator';\r\n\r\nimport FilelistNew from '@/routes/Sidebar/routes/Filelists/components/FilelistNew';\r\nimport FilelistSession from '@/routes/Sidebar/routes/Filelists/components/FilelistSession';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport {\r\n SessionProviderDecorator,\r\n SessionProviderDecoratorChildProps,\r\n} from '@/routes/Sidebar/decorators/SessionProviderDecorator';\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport { FilelistSessionActionMenu } from '@/actions/ui/filelist';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { FilelistStoreSelector } from '@/stores/session/filelistSlice';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\nconst UserItemHandler = UserItemHandlerDecorator(['message']);\r\nconst ItemHandler: UI.SessionInfoGetter<API.FilelistSession> = {\r\n itemLabelGetter() {\r\n return null;\r\n },\r\n\r\n itemNameGetter(session) {\r\n return session.share_profile\r\n ? session.share_profile.str\r\n : UserItemHandler.itemNameGetter(session);\r\n },\r\n\r\n itemStatusGetter(session) {\r\n return session.share_profile ? 'blue' : UserItemHandler.itemStatusGetter!(session);\r\n },\r\n\r\n itemHeaderTitleGetter(session, location, actionMenu) {\r\n return session.share_profile\r\n ? actionMenu\r\n : UserItemHandler.itemHeaderTitleGetter!(session, location, actionMenu);\r\n },\r\n\r\n itemHeaderDescriptionGetter(session) {\r\n return session.share_profile\r\n ? null\r\n : UserItemHandler.itemHeaderDescriptionGetter(session);\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return session.share_profile\r\n ? 'green server'\r\n : UserItemHandler.itemHeaderIconGetter(session);\r\n },\r\n};\r\n\r\nconst Filelists: React.FC<SessionProviderDecoratorChildProps<API.FilelistSession>> = (\r\n props,\r\n) => {\r\n const { params, sessionT, ...other } = props;\r\n return (\r\n <SessionLayout\r\n activeId={params.id}\r\n baseUrl=\"filelists\"\r\n newCaption={sessionT.t('new', 'Open filelist')}\r\n newDescription={sessionT.t('newDesc', 'Start browsing a new filelist')}\r\n newIcon={IconConstants.FILELISTS_PLAIN}\r\n disableSideMenu={true}\r\n editAccess={API.AccessEnum.FILELISTS_EDIT}\r\n uiActions={FilelistSessionActionMenu}\r\n sessionApi={FilelistAPIActions}\r\n sessionStoreSelector={FilelistStoreSelector}\r\n sessionItemLayout={FilelistSession}\r\n newLayout={FilelistNew}\r\n sessionT={sessionT}\r\n remoteMenuId={MenuConstants.FILELIST}\r\n {...ItemHandler}\r\n {...other}\r\n />\r\n );\r\n};\r\n\r\nexport default SessionProviderDecorator(\r\n Filelists,\r\n FilelistStoreSelector,\r\n UI.Modules.FILELISTS,\r\n);\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.fileitem.info.segment .dupe-paths .path {\n overflow-x: hidden;\n}\n\n.fileitem.info.segment .download.ui.dropdown {\n max-width: 150px;\n margin-top: 10px;\n}\n\n.fileitem.info.segment .title.column {\n margin-top: auto;\n margin-bottom: auto;\n}\n\n.fileitem.info.segment .value.column {\n word-break: break-all;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/file-item-info/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,qBAAqB;AACvB\",\"sourcesContent\":[\".fileitem.info.segment .dupe-paths .path {\\n overflow-x: hidden;\\n}\\n\\n.fileitem.info.segment .download.ui.dropdown {\\n max-width: 150px;\\n margin-top: 10px;\\n}\\n\\n.fileitem.info.segment .title.column {\\n margin-top: auto;\\n margin-bottom: auto;\\n}\\n\\n.fileitem.info.segment .value.column {\\n word-break: break-all;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import ShareConstants from '@/constants/ShareConstants';\r\nimport { APISocket } from '@/services/SocketService';\r\n\r\nimport { uploadTempFile } from '../HttpService';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface AddTempShareResponse {\r\n magnet: string;\r\n}\r\n\r\ninterface TempFileData {\r\n file: File;\r\n hubUrl: string;\r\n cid?: string;\r\n}\r\n\r\nexport const shareTempFile = async (\r\n { file, hubUrl, cid }: TempFileData,\r\n { auth_token: authToken }: UI.AuthenticatedSession,\r\n socket: APISocket,\r\n): Promise<AddTempShareResponse> => {\r\n // eslint-disable-next-line no-useless-catch\r\n try {\r\n const fileId = await uploadTempFile(file, authToken);\r\n const res = await socket.post<AddTempShareResponse>(ShareConstants.TEMP_SHARES_URL, {\r\n name: file.name,\r\n file_id: fileId,\r\n hub_url: hubUrl,\r\n cid,\r\n });\r\n\r\n return res;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nexport const refresh = (incoming: boolean, socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_URL, {\r\n incoming,\r\n priority: API.RefreshPriorityTypeEnum.MANUAL,\r\n });\r\n};\r\n\r\nexport const refreshPaths = (paths: string[], socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_PATHS_URL, {\r\n paths,\r\n priority: API.RefreshPriorityTypeEnum.MANUAL,\r\n });\r\n};\r\n\r\nexport const refreshVirtual = (path: string, socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_VIRTUAL_URL, {\r\n path,\r\n });\r\n};\r\n\r\nexport const abortRefreshTask = (id: number, socket: APISocket) => {\r\n return socket.delete(`${ShareConstants.REFRESH_TASKS_URL}/${id}`);\r\n};\r\n","import * as React from 'react';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from '@/decorators/DataProviderDecorator';\r\nimport { useFormatter } from '@/context/FormatterContext';\r\n\r\nimport LayoutHeader from '@/components/semantic/LayoutHeader';\r\nimport { ListItem } from '@/components/semantic/List';\r\n\r\nimport HistoryConstants, { HistoryEntryEnum } from '@/constants/HistoryConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { translate, toI18nKey } from '@/utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\ninterface RecentLayoutProps {\r\n // Title of the button\r\n entryIcon: string;\r\n\r\n // URL for fetching the recent entries\r\n entryType: HistoryEntryEnum;\r\n\r\n // Renders the recent entry title\r\n entryTitleRenderer: (entry: API.HistoryItem) => React.ReactNode;\r\n\r\n // Returns whether the recent entry is currently active\r\n hasSession: (entry: API.HistoryItem) => boolean;\r\n}\r\n\r\ninterface DataProps {\r\n entries: API.HistoryItem[];\r\n}\r\n\r\ntype Props = RecentLayoutProps & DataProps & DataProviderDecoratorChildProps;\r\n\r\nconst RecentLayout: React.FC<Props> = ({\r\n entries,\r\n entryTitleRenderer,\r\n hasSession,\r\n entryIcon,\r\n}) => {\r\n const { formatRelativeTime } = useFormatter();\r\n const { t } = useTranslation();\r\n if (entries.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"recents\">\r\n <LayoutHeader title={translate('Recent sessions', t, UI.Modules.COMMON)} size=\"\" />\r\n <div className=\"ui relaxed divided list\">\r\n {entries.map((entry, index) => (\r\n <ListItem\r\n key={index}\r\n header={entryTitleRenderer(entry)}\r\n description={\r\n !!entry.last_opened &&\r\n t(toI18nKey('openedAgo', UI.Modules.COMMON), {\r\n defaultValue: 'Opened {{timeAgo}}',\r\n replace: {\r\n timeAgo: formatRelativeTime(entry.last_opened),\r\n },\r\n })\r\n }\r\n icon={(hasSession(entry) ? 'green ' : '') + entryIcon}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport const getHistoryUrl = (entryType: HistoryEntryEnum) => {\r\n return `${HistoryConstants.SESSIONS_URL}/${entryType}/0`;\r\n};\r\n\r\nexport default DataProviderDecorator<RecentLayoutProps, DataProps>(\r\n //RedrawDecorator<Props>(RecentLayout),\r\n RecentLayout,\r\n {\r\n urls: {\r\n entries: ({ entryType }, socket) => socket.get(getHistoryUrl(entryType)),\r\n },\r\n },\r\n);\r\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from '@/constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n DataProviderDecoratorSettings,\r\n DataConverter,\r\n} from '@/decorators/DataProviderDecorator';\r\n\r\nimport * as API from '@/types/api';\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps &\r\n ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>,\r\n listHidden: boolean,\r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<\r\n PropsT,\r\n ShareProfileDecoratorDataProps\r\n >,\r\n) {\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data.filter(\r\n (p) => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID,\r\n );\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component,\r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_ADDED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_UPDATED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_REMOVED,\r\n () => refetchData(),\r\n );\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>),\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","const MODULE_URL = 'share_profiles';\nexport default {\n MODULE_URL: MODULE_URL,\n PROFILES_URL: MODULE_URL,\n\n PROFILE_ADDED: 'share_profile_added',\n PROFILE_UPDATED: 'share_profile_updated',\n PROFILE_REMOVED: 'share_profile_removed',\n\n HIDDEN_PROFILE_ID: 1,\n};\n","import { fetchData } from '@/utils/HttpUtils';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport const uploadTempFile = async (file: File, authToken: string): Promise<string> => {\r\n // eslint-disable-next-line no-useless-catch\r\n try {\r\n const res = await fetchData(`${getBasePath()}temp`, {\r\n method: 'POST',\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': authToken,\r\n\r\n Authorization: authToken,\r\n },\r\n body: file,\r\n });\r\n\r\n return res.headers.get('Location')!;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nconst toCorsSafeUrl = (url: string) => {\r\n const proxyUrl = `${\r\n window.location.origin\r\n }${getBasePath()}proxy?url=${encodeURIComponent(url)}`;\r\n return proxyUrl;\r\n};\r\n\r\ninterface FetchDataOptions extends RequestInit {\r\n isJSON?: boolean;\r\n}\r\n\r\nexport const fetchCorsSafeData = async (\r\n url: string,\r\n session: UI.AuthenticatedSession,\r\n options: FetchDataOptions = { isJSON: true },\r\n) => {\r\n try {\r\n //console.log(`CORS HTTP request started (${url})`);\r\n\r\n const res = await fetchData(toCorsSafeUrl(url), {\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': session.auth_token,\r\n\r\n // Temp workaround for people upgrading from versions < 2.7.0\r\n // If the new UI was loaded before restarting the app, a cache expiration time of\r\n // one year would have been set for \"Not found\" errors...\r\n 'Cache-Control': 'no-store, must-revalidate, max-age=0',\r\n },\r\n ...options,\r\n });\r\n\r\n const data = (await options.isJSON) ? res.json() : res.text();\r\n return data;\r\n } catch (e) {\r\n console.error(`CORS HTTP request failed (${url})`, e);\r\n throw e;\r\n }\r\n};\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from '@/context/FormatterContext';\r\n\r\nimport { DownloadMenu } from '@/components/action-menu';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { useTranslation } from 'react-i18next';\r\nimport { translate } from '@/utils/TranslationUtils';\r\n\r\nimport './style.css';\r\nimport { Row, Grid } from '@/components/semantic/Grid';\r\n\r\nconst DupeStrings = {\r\n //[API.DupeEnum.NONE]: 'None',\r\n [API.DupeEnum.SHARE_PARTIAL]: 'Share (partial)',\r\n [API.DupeEnum.SHARE_FULL]: 'Share (full)',\r\n [API.DupeEnum.QUEUE_PARTIAL]: 'Queue (partial)',\r\n [API.DupeEnum.QUEUE_FULL]: 'Queue (full)',\r\n [API.DupeEnum.FINISHED_PARTIAL]: 'Finished (partial)',\r\n [API.DupeEnum.FINISHED_FULL]: 'Finished (full)',\r\n [API.DupeEnum.SHARE_QUEUE]: 'Share and queue',\r\n [API.DupeEnum.SHARE_FINISHED]: 'Share and finished',\r\n [API.DupeEnum.QUEUE_FINISHED]: 'Queue and finished',\r\n [API.DupeEnum.SHARE_QUEUE_FINISHED]: 'Share, queue and finished',\r\n};\r\n\r\nconst DupePaths: React.FC<{ paths: string[] }> = ({ paths }) => (\r\n <div className=\"dupe-paths\">\r\n {paths.map((path) => (\r\n <div key={path} className=\"path\">\r\n {path}\r\n </div>\r\n ))}\r\n </div>\r\n);\r\n\r\ninterface FileItemInfoGridProps {\r\n fileItem: UI.DownloadableItemInfo;\r\n user: API.HintedUser;\r\n downloadHandler: UI.DownloadHandler<UI.DownloadableItemInfo>;\r\n showPath?: boolean;\r\n sessionItem: UI.SessionItemBase;\r\n}\r\n\r\nconst FileItemInfoGrid: React.FC<FileItemInfoGridProps> = ({\r\n sessionItem,\r\n fileItem,\r\n user,\r\n downloadHandler,\r\n showPath = true,\r\n}) => {\r\n const { t } = useTranslation();\r\n const gridT = (text: string) => {\r\n return translate(text, t, UI.Modules.COMMON);\r\n };\r\n\r\n const { formatSize, formatRelativeTime } = useFormatter();\r\n return (\r\n <div className=\"ui fileitem info segment\">\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={gridT('Name')} text={fileItem.name} />\r\n <Row title={gridT('Type/content')} text={fileItem.type.str} />\r\n <Row title={gridT('Size')} text={formatSize(fileItem.size, 2, true)} />\r\n <Row\r\n title={gridT('Last modified')}\r\n text={formatRelativeTime(fileItem.time || 0)}\r\n />\r\n {fileItem.type.id === 'file' && <Row title={gridT('TTH')} text={fileItem.tth} />}\r\n {!!fileItem.dupe && (\r\n <Row title={gridT('Dupe type')} text={gridT(DupeStrings[fileItem.dupe.id])} />\r\n )}\r\n {!!fileItem.dupe && (\r\n <Row\r\n title={gridT('Dupe paths')}\r\n text={<DupePaths paths={fileItem.dupe.paths} />}\r\n />\r\n )}\r\n {showPath && <Row title={gridT('Path')} text={fileItem.path} />}\r\n </Grid>\r\n\r\n <DownloadMenu\r\n caption={gridT('Actions...')}\r\n button={true}\r\n user={user}\r\n itemInfoGetter={() => fileItem}\r\n downloadHandler={downloadHandler}\r\n contextElement=\".ui.modal > .content\"\r\n entity={sessionItem}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport { FileItemInfoGrid };\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#sidebar .virtual-table {\n flex: 1 100 100%;\n}\n\n.filelist.session .browser,\n.filelist.session .browser .virtual-table {\n height: calc(100% - 35px);\n}\n\n#mobile-layout .filelist.session .browser {\n height: 100%;\n}\n\n#mobile-layout .filelist.session .browser {\n height: calc(100% - 10px);\n}\n\n@media screen and (min-color-index: 0) and(-webkit-min-device-pixel-ratio:0) {\n /* Safari specific CSS */\n .filelist.session .browser {\n height: calc(100% - 95px);\n }\n\n #mobile-layout .filelist.session .browser {\n height: calc(100% - 60px);\n }\n}\n\n.filelist.session .browser .ui.segment {\n margin-bottom: 10px;\n}\n\n.filelist.session {\n max-height: 100%;\n overflow: hidden;\n margin-top: 10px;\n flex: 1 1 100%;\n}\n\n.session.new .profile.ui.dropdown {\n margin-top: 10px;\n color: gray;\n align-self: flex-end;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/routes/Filelists/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,yBAAyB;AAC3B;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,yBAAyB;AAC3B;;AAEA;EACE,wBAAwB;EACxB;IACE,yBAAyB;EAC3B;;EAEA;IACE,yBAAyB;EAC3B;AACF;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,WAAW;EACX,oBAAoB;AACtB\",\"sourcesContent\":[\"#sidebar .virtual-table {\\n flex: 1 100 100%;\\n}\\n\\n.filelist.session .browser,\\n.filelist.session .browser .virtual-table {\\n height: calc(100% - 35px);\\n}\\n\\n#mobile-layout .filelist.session .browser {\\n height: 100%;\\n}\\n\\n#mobile-layout .filelist.session .browser {\\n height: calc(100% - 10px);\\n}\\n\\n@media screen and (min-color-index: 0) and(-webkit-min-device-pixel-ratio:0) {\\n /* Safari specific CSS */\\n .filelist.session .browser {\\n height: calc(100% - 95px);\\n }\\n\\n #mobile-layout .filelist.session .browser {\\n height: calc(100% - 60px);\\n }\\n}\\n\\n.filelist.session .browser .ui.segment {\\n margin-bottom: 10px;\\n}\\n\\n.filelist.session {\\n max-height: 100%;\\n overflow: hidden;\\n margin-top: 10px;\\n flex: 1 1 100%;\\n}\\n\\n.session.new .profile.ui.dropdown {\\n margin-top: 10px;\\n color: gray;\\n align-self: flex-end;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n"],"names":["formatProfileNameWithSize","profile","formatSize","str","id","HIDDEN_PROFILE_ID","size","profileToEnumValue","formatter","name","itemMenuIds","itemNameGetter","session","user","nicks","itemStatusGetter","flags","itemHeaderDescriptionGetter","hub_names","itemHeaderIconGetter","itemHeaderTitleGetter","location","actionMenu","ids","remoteMenuId","HINTED_USER","ShareProfileDecorator","sessionT","profiles","onProfileChanged","Dropdown","className","caption","translate","triggerIcon","map","MenuItemLink","onClick","navigate","sessionStore","socket","createSessionProps","t","plainT","handleSubmit","createRemoteSession","onChange","offlineMessage","isClearable","autoFocus","shareProfileId","initCreateLocalSession","RecentLayout","entryType","FILELIST","hasSession","entry","filelists","getSession","cid","entryTitleRenderer","description","LinkButton","_","entryIcon","IconConstants","FILELISTS_PLAIN","filelist","locationText","type","length","SessionFooter","label","text","total_size","FilelistItemGetter","itemId","get","FilelistConstants","MODULE_URL","FilelistItemInfoDialog","Component","render","fileItem","this","props","RouteModal","title","closable","icon","FileIcon","typeInfo","fullHeight","DownloadDialog","downloadHandler","itemDataGetter","userGetter","sessionItem","displayName","Decorated","ModalRouteDecorator","DataProviderDecorator","urls","params","_viewName","VIEW_ID","_apiUrl","SESSIONS_URL","mixins","ViewStoreMixin","FilelistItemActions","reloadDirectory","access","FILELISTS_VIEW","RELOAD","filter","data","entity","partial_list","isPartialList","itemData","isDirectory","handler","item","post","list_path","path","reload","refreshShare","SETTINGS_EDIT","REFRESH_COLORED","includes","details","DETAILS","isRoot","FilelistItemActionMenu","moduleData","moduleId","FILELISTS","subId","actions","FilelistSessionActions","remove","FILELISTS_EDIT","FilelistSessionActionMenu","NameCell","rowDataGetter","captionGetter","other","MenuConstants","FILELIST_ITEM","onClickDirectory","VirtualTable","emptyRowsNodeGetter","state","Message","ERROR","files","directories","Loader","complete","rowClassNameGetter","rowData","dupe","store","FilelistViewStore","entityId","viewId","textFilterProps","width","columnKey","cell","cellData","flexGrow","hideWidth","hasClickedDirectory","setHasClickedDirectory","updateLocationState","directory","replace","locationState","newState","pathname","apiSendChangeDirectory","useSyncFilelistLocation","handleClickDirectory","currentLocation","nextLocation","historyAction","NotificationActions","info","message","getCurrentDirectory","filelistItemFetcher","BrowserBar","separator","rootPath","rootName","itemClickHandler","selectedNameFormatter","itemInfoGetter","contextElement","routerLocation","listLocation","isOwnList","self","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","UserItemHandler","UserItemHandlerDecorator","ItemHandler","itemLabelGetter","share_profile","SessionProviderDecorator","SessionLayout","activeId","baseUrl","newCaption","newDescription","newIcon","disableSideMenu","editAccess","uiActions","sessionApi","sessionStoreSelector","sessionItemLayout","newLayout","___CSS_LOADER_EXPORT___","push","module","shareTempFile","file","hubUrl","auth_token","authToken","fileId","TEMP_SHARES_URL","file_id","hub_url","e","refreshPaths","paths","REFRESH_PATHS_URL","priority","MANUAL","refreshVirtual","REFRESH_VIRTUAL_URL","abortRefreshTask","delete","REFRESH_TASKS_URL","entries","formatRelativeTime","COMMON","index","header","last_opened","defaultValue","timeAgo","getHistoryUrl","listHidden","dataProviderDecoratorSettings","merge","PROFILES_URL","dataConverters","p","onSocketConnected","addSocketListener","refetchData","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","uploadTempFile","getBasePath","method","headers","Authorization","body","fetchCorsSafeData","url","isJSON","res","window","origin","encodeURIComponent","toCorsSafeUrl","json","console","error","DupeStrings","SHARE_PARTIAL","SHARE_FULL","QUEUE_PARTIAL","QUEUE_FULL","FINISHED_PARTIAL","FINISHED_FULL","SHARE_QUEUE","SHARE_FINISHED","QUEUE_FINISHED","SHARE_QUEUE_FINISHED","DupePaths","FileItemInfoGrid","showPath","gridT","Grid","columns","stackable","time","tth","button"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"js/filelists.f098fc396efc445ef837.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/utils/ShareProfileUtils.ts","webpack://airdcpp-webui/./src/routes/Sidebar/decorators/UserItemHandlerDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/ShareProfileSelector.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistNew.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/item-info-dialog/FilelistItemInfoDialog.tsx","webpack://airdcpp-webui/./src/stores/views/FilelistViewStore.js","webpack://airdcpp-webui/./src/actions/ui/filelist/FilelistItemActions.ts","webpack://airdcpp-webui/./src/actions/ui/filelist/FilelistSessionActions.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistItemTable.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/ListBrowser.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/effects/useSyncFilelistLocation.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/FilelistSession.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/style.css?8d81","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/components/Filelists.tsx","webpack://airdcpp-webui/./src/components/file-item-info/style.css","webpack://airdcpp-webui/./src/services/api/ShareApi.ts","webpack://airdcpp-webui/./src/routes/Sidebar/components/RecentLayout.tsx","webpack://airdcpp-webui/./src/decorators/ShareProfileDecorator.tsx","webpack://airdcpp-webui/./src/constants/ShareProfileConstants.ts","webpack://airdcpp-webui/./src/services/HttpService.ts","webpack://airdcpp-webui/./src/components/file-item-info/style.css?a322","webpack://airdcpp-webui/./src/components/file-item-info/FileItemInfoGrid.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Filelists/style.css"],"sourcesContent":["import ShareProfileConstants from '@/constants/ShareProfileConstants';\r\n\r\nimport { Formatter } from '@/context/FormatterContext';\r\n\r\nimport * as API from '@/types/api';\r\n\r\nexport const formatProfileNameWithSize = (\r\n profile: API.ShareProfile,\r\n { formatSize }: Formatter,\r\n) => {\r\n let str = profile.str;\r\n if (profile.id !== ShareProfileConstants.HIDDEN_PROFILE_ID) {\r\n str += ` (${formatSize(profile.size)})`;\r\n }\r\n\r\n return str;\r\n};\r\n\r\nexport const profileToEnumValue = (profile: API.ShareProfile, formatter: Formatter) => {\r\n return {\r\n id: profile.id,\r\n name: formatProfileNameWithSize(profile, formatter),\r\n };\r\n};\r\n","import { userOnlineStatusToColor } from '@/utils/TypeConvert';\r\nimport { UserMenu } from '@/components/action-menu';\r\nimport UserIcon from '@/components/icon/UserIcon';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\ninterface UserSessionBase {\r\n user: API.HintedUser;\r\n}\r\n\r\nexport default function <SessionT extends UI.SessionItemBase & UserSessionBase>(\r\n itemMenuIds: string[],\r\n) {\r\n const UserItemHandlerDecorator: UI.SessionInfoGetter<SessionT> = {\r\n itemNameGetter(session) {\r\n return session.user.nicks;\r\n },\r\n\r\n itemStatusGetter(session) {\r\n const { flags } = session.user;\r\n return userOnlineStatusToColor(flags);\r\n },\r\n\r\n itemHeaderDescriptionGetter(session) {\r\n return session.user.hub_names;\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return <UserIcon flags={session.user.flags} />;\r\n },\r\n\r\n itemHeaderTitleGetter(session, location, actionMenu) {\r\n const { user } = session;\r\n return (\r\n <UserMenu user={user} ids={itemMenuIds} remoteMenuId={MenuConstants.HINTED_USER}>\r\n {actionMenu}\r\n </UserMenu>\r\n );\r\n },\r\n };\r\n\r\n return UserItemHandlerDecorator;\r\n}\r\n","import Dropdown from '@/components/semantic/Dropdown';\nimport MenuItemLink from '@/components/semantic/MenuItemLink';\n\nimport ShareProfileDecorator, {\n ShareProfileDecoratorChildProps,\n} from '@/decorators/ShareProfileDecorator';\n\nimport * as API from '@/types/api';\nimport * as UI from '@/types/ui';\n\nimport { formatProfileNameWithSize } from '@/utils/ShareProfileUtils';\nimport { useFormatter } from '@/context/FormatterContext';\n\ninterface ShareProfileSelectorProps {\n // Callback after selecting a profile\n onProfileChanged: (profileId: number) => void;\n\n sessionT: UI.ModuleTranslator;\n}\n\nconst ShareProfileSelector: React.FC<\n ShareProfileSelectorProps & ShareProfileDecoratorChildProps\n> = ({ sessionT, profiles, onProfileChanged }) => {\n const formatter = useFormatter();\n\n const getDropdownItem = (profile: API.ShareProfile) => {\n return (\n <MenuItemLink key={profile.id} onClick={() => onProfileChanged(profile.id)}>\n {formatProfileNameWithSize(profile, formatter)}\n </MenuItemLink>\n );\n };\n\n return (\n <Dropdown\n className=\"profile top right pointing\"\n caption={sessionT.translate('Browse own share...')}\n triggerIcon=\"\"\n >\n {profiles.map(getDropdownItem)}\n </Dropdown>\n );\n};\n\nexport default ShareProfileDecorator(ShareProfileSelector, false);\n","import RecentLayout from '@/routes/Sidebar/components/RecentLayout';\r\n\r\nimport ShareProfileSelector from '@/routes/Sidebar/routes/Filelists/components/ShareProfileSelector';\r\nimport { HistoryEntryEnum } from '@/constants/HistoryConstants';\r\n\r\nimport * as API from '@/types/api';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport { UserSelectField } from '@/components/select';\r\nimport { NewSessionLayoutProps } from '@/routes/Sidebar/components/types';\r\nimport LinkButton from '@/components/semantic/LinkButton';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { useSessionStore } from '@/context/SessionStoreContext';\r\nimport { useSocket } from '@/context/SocketContext';\r\nimport { useSession } from '@/context/AppStoreContext';\r\n\r\nconst FilelistNew: React.FC<NewSessionLayoutProps> = ({ navigate, sessionT }) => {\r\n const sessionStore = useSessionStore();\r\n const socket = useSocket();\r\n const session = useSession();\r\n\r\n const createSessionProps = {\r\n sessionStore,\r\n socket,\r\n navigate,\r\n t: sessionT.plainT,\r\n };\r\n\r\n const handleSubmit = (user: API.HintedUser) => {\r\n FilelistAPIActions.createRemoteSession({ user }, createSessionProps);\r\n };\r\n\r\n const onProfileChanged = (shareProfileId: number) => {\r\n FilelistAPIActions.initCreateLocalSession(session)(\r\n { shareProfileId },\r\n createSessionProps,\r\n );\r\n };\r\n\r\n const recentUserRender = (entry: API.HistoryItem) => {\r\n const caption =\r\n entry.user!.nicks + (entry.description ? ` (${entry.description})` : '');\r\n return <LinkButton onClick={(_) => handleSubmit(entry.user!)} caption={caption} />;\r\n };\r\n\r\n const hasSession = (entry: API.HistoryItem) => {\r\n return !!sessionStore.filelists.getSession(entry.user!.cid);\r\n };\r\n\r\n return (\r\n <div className=\"filelist session new\">\r\n <UserSelectField\r\n onChange={handleSubmit}\r\n offlineMessage={sessionT.t(\r\n 'offlineMessage',\r\n 'You must to be connected to at least one hub in order to download filelists from other users',\r\n )}\r\n isClearable={false}\r\n autoFocus={true}\r\n />\r\n <ShareProfileSelector onProfileChanged={onProfileChanged} sessionT={sessionT} />\r\n <RecentLayout\r\n entryType={HistoryEntryEnum.FILELIST}\r\n hasSession={hasSession}\r\n entryTitleRenderer={recentUserRender}\r\n entryIcon={IconConstants.FILELISTS_PLAIN}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FilelistNew;\r\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from '@/context/FormatterContext';\r\nimport { FooterItem, SessionFooter } from '@/routes/Sidebar/components/SessionFooter';\r\nimport { usingMobileLayout } from '@/utils/BrowserUtils';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\ninterface FilelistFooterProps {\r\n filelist: API.FilelistSession;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FilelistFooter: React.FC<FilelistFooterProps> = ({ filelist, sessionT }) => {\r\n const { formatSize } = useFormatter();\r\n if (usingMobileLayout()) {\r\n return null;\r\n }\r\n\r\n let locationText = filelist.location!.type.str;\r\n if (locationText.length > 0) {\r\n locationText = `${formatSize(filelist.location!.size)} (${locationText})`;\r\n }\r\n\r\n return (\r\n <SessionFooter>\r\n <FooterItem label={sessionT.translate('Directory size')} text={locationText} />\r\n <FooterItem\r\n label={sessionT.translate('Total list size')}\r\n text={formatSize(filelist.total_size)}\r\n />\r\n </SessionFooter>\r\n );\r\n};\r\n\r\nexport default FilelistFooter;\r\n","import { Component } from 'react';\r\nimport RouteModal from '@/components/semantic/RouteModal';\r\n\r\nimport FileIcon from '@/components/icon/FileIcon';\r\n\r\nimport DownloadDialog from '@/components/download/DownloadDialog';\r\n\r\nimport ModalRouteDecorator, {\r\n ModalRouteDecoratorChildProps,\r\n} from '@/decorators/ModalRouteDecorator';\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from '@/decorators/DataProviderDecorator';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FileItemInfoGrid } from '@/components/file-item-info';\r\nimport FilelistConstants from '@/constants/FilelistConstants';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\n\r\ninterface FilelistItemInfoDialogProps {\r\n filelist: API.FilelistSession;\r\n}\r\n\r\ninterface DataProps extends DataProviderDecoratorChildProps {\r\n fileItem: API.FilelistItem;\r\n}\r\n\r\ntype Props = FilelistItemInfoDialogProps & ModalRouteDecoratorChildProps;\r\n\r\nexport const FilelistItemGetter = (filelist: API.FilelistSession) => {\r\n const ret: UI.DownloadItemDataGetter<API.FilelistItem> = (itemId, socket) => {\r\n return socket.get(`${FilelistConstants.MODULE_URL}/${filelist.id}/items/${itemId}`);\r\n };\r\n\r\n return ret;\r\n};\r\n\r\nclass FilelistItemInfoDialog extends Component<Props & DataProps> {\r\n static readonly displayName = 'FilelistItemInfoDialog';\r\n\r\n render() {\r\n const { fileItem, filelist } = this.props;\r\n return (\r\n <RouteModal\r\n className=\"filelist-item\"\r\n title={fileItem.name}\r\n closable={true}\r\n icon={<FileIcon typeInfo={fileItem.type} />}\r\n fullHeight={true}\r\n {...this.props}\r\n >\r\n <DownloadDialog\r\n downloadHandler={filelistDownloadHandler}\r\n itemDataGetter={FilelistItemGetter(filelist)}\r\n userGetter={() => filelist.user}\r\n sessionItem={filelist}\r\n />\r\n <FileItemInfoGrid\r\n fileItem={fileItem}\r\n downloadHandler={filelistDownloadHandler}\r\n user={filelist.user}\r\n sessionItem={filelist}\r\n />\r\n </RouteModal>\r\n );\r\n }\r\n}\r\n\r\nconst Decorated = ModalRouteDecorator<FilelistItemInfoDialogProps>(\r\n DataProviderDecorator<Props, DataProps>(FilelistItemInfoDialog, {\r\n urls: {\r\n fileItem: ({ params, filelist }, socket) =>\r\n FilelistItemGetter(filelist)(params.itemId!, socket),\r\n },\r\n }),\r\n 'item/:itemId',\r\n);\r\n\r\nexport { Decorated as FilelistItemInfoDialog };\r\n","import ViewStoreMixin from '@/mixins/ViewStoreMixin';\nimport Reflux from 'reflux';\nimport FilelistConstants from '@/constants/FilelistConstants';\n// import FilelistSessionStore from '../reflux/FilelistSessionStore.ts.tmp';\n\nexport default Reflux.createStore({\n _viewName: `${FilelistConstants.VIEW_ID}_view`,\n _apiUrl: FilelistConstants.SESSIONS_URL,\n // _sessionStore: FilelistSessionStore,\n mixins: [ViewStoreMixin('name')],\n});\n","import FilelistConstants from '@/constants/FilelistConstants';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { refreshVirtual } from '@/services/api/ShareApi';\r\n\r\ntype Filter = UI.ActionFilter<API.FilelistItem, API.FilelistSession>;\r\n\r\n// Filters\r\nconst isMe: Filter = ({ entity }) => entity.user.flags.includes('self');\r\nconst isRoot: Filter = ({ itemData }) => itemData.path === '/';\r\nconst isPartialList: Filter = ({ entity }) => entity.partial_list;\r\nconst isDirectory: Filter = ({ itemData }) => itemData.type.id === 'directory';\r\n\r\nconst filterReload: Filter = (data) => isPartialList(data) && isDirectory(data);\r\nconst filterDetails: Filter = (data) => !isRoot(data);\r\n\r\n// Handlers\r\ntype Handler = UI.ActionHandler<API.FilelistItem, API.FilelistSession>;\r\n\r\nconst handleReloadDirectory: Handler = ({ itemData: item, entity: session, socket }) => {\r\n return socket.post(`${FilelistConstants.SESSIONS_URL}/${session.id}/directory`, {\r\n list_path: item.path,\r\n reload: true,\r\n });\r\n};\r\n\r\nconst handleRefreshShare: Handler = ({ itemData, socket }) => {\r\n return refreshVirtual(itemData.path, socket);\r\n};\r\n\r\nconst handleItemDetails: Handler = ({ itemData, navigate }) => {\r\n navigate(`item/${itemData.id}`);\r\n};\r\n\r\n// Actions\r\nexport const FilelistItemReloadDirectoryAction = {\r\n id: 'reloadDirectory',\r\n displayName: 'Reload',\r\n access: API.AccessEnum.FILELISTS_VIEW,\r\n icon: IconConstants.RELOAD,\r\n filter: filterReload,\r\n handler: handleReloadDirectory,\r\n};\r\n\r\nexport const FilelistItemRefreshShareAction = {\r\n id: 'refreshShare',\r\n displayName: 'Refresh in share',\r\n access: API.AccessEnum.SETTINGS_EDIT,\r\n icon: IconConstants.REFRESH_COLORED,\r\n filter: isMe,\r\n handler: handleRefreshShare,\r\n};\r\n\r\nexport const FilelistItemDetailsAction = {\r\n id: 'details',\r\n displayName: 'Details',\r\n icon: IconConstants.DETAILS,\r\n handler: handleItemDetails,\r\n filter: filterDetails,\r\n};\r\n\r\nconst FilelistItemActions: UI.ActionListType<API.FilelistItem, API.FilelistSession> = {\r\n reloadDirectory: FilelistItemReloadDirectoryAction,\r\n refreshShare: FilelistItemRefreshShareAction,\r\n details: FilelistItemDetailsAction,\r\n};\r\n\r\nexport const FilelistItemActionModule = {\r\n moduleId: UI.Modules.FILELISTS,\r\n subId: 'item',\r\n};\r\n\r\nexport const FilelistItemActionMenu = {\r\n moduleData: FilelistItemActionModule,\r\n actions: FilelistItemActions,\r\n};\r\n","import FilelistConstants from '@/constants/FilelistConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { BuildRemoveSessionAction } from '../decorators/SessionActionDecorator';\r\n\r\nconst FilelistRemoveAction = BuildRemoveSessionAction(\r\n FilelistConstants.SESSIONS_URL,\r\n API.AccessEnum.FILELISTS_EDIT,\r\n);\r\n\r\nconst FilelistSessionActions: UI.ActionListType<API.FilelistSession> = {\r\n remove: FilelistRemoveAction,\r\n};\r\n\r\nexport const FilelistSessionActionModule = {\r\n moduleId: UI.Modules.FILELISTS,\r\n};\r\n\r\nexport const FilelistSessionActionMenu = {\r\n moduleData: FilelistSessionActionModule,\r\n actions: FilelistSessionActions,\r\n};\r\n","import * as React from 'react';\r\n\r\nimport { dupeToStringType } from '@/utils/TypeConvert';\r\nimport { TableActionMenu } from '@/components/action-menu';\r\n\r\nimport FilelistViewStore from '@/stores/views/FilelistViewStore';\r\n\r\nimport VirtualTable from '@/components/table/VirtualTable';\r\nimport {\r\n SizeCell,\r\n DurationCell,\r\n FileDownloadCell,\r\n FileDownloadCellCaptionGetter,\r\n} from '@/components/table/Cell';\r\nimport { Column } from 'fixed-data-table-2';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FilelistItemInfoDialog } from './item-info-dialog';\r\nimport { RowWrapperCellChildProps } from '@/components/table/RowWrapperCell';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\nimport { FilelistItemActionMenu } from '@/actions/ui/filelist';\r\nimport { useSessionStore } from '@/context/SessionStoreContext';\r\nimport LinkButton from '@/components/semantic/LinkButton';\r\n\r\ninterface NameCellProps extends RowWrapperCellChildProps<string, API.FilelistItem> {\r\n filelist: API.FilelistSession;\r\n captionGetter: FileDownloadCellCaptionGetter;\r\n}\r\n\r\nconst NameCell: React.FC<NameCellProps> = ({\r\n rowDataGetter,\r\n captionGetter,\r\n filelist,\r\n ...other\r\n}) => {\r\n return (\r\n <FileDownloadCell\r\n userGetter={() => filelist.user}\r\n downloadHandler={filelistDownloadHandler}\r\n rowDataGetter={rowDataGetter}\r\n entity={filelist}\r\n remoteMenuId={MenuConstants.FILELIST_ITEM}\r\n captionGetter={captionGetter}\r\n {...other}\r\n >\r\n <TableActionMenu\r\n actions={FilelistItemActionMenu}\r\n itemData={rowDataGetter}\r\n ids={['refreshShare', 'details']}\r\n entity={filelist}\r\n />\r\n </FileDownloadCell>\r\n );\r\n};\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n onClickDirectory: (path: string) => void;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FilelistItemTable: React.FC<ListBrowserProps> = ({\r\n filelist,\r\n sessionT,\r\n onClickDirectory,\r\n ...other\r\n}) => {\r\n const rowClassNameGetter = (rowData: API.FilelistItem) => {\r\n // Don't highlight dupes in own filelist...\r\n const isOwnList = filelist.user.flags.includes('self');\r\n return isOwnList ? '' : dupeToStringType(rowData.dupe);\r\n };\r\n\r\n const emptyRowsNodeGetter = () => {\r\n const { location, state } = filelist;\r\n const { translate } = sessionT;\r\n\r\n if (state.id === 'download_failed') {\r\n return (\r\n <Message\r\n icon={IconConstants.ERROR}\r\n title={translate('Download failed')}\r\n description={state.str}\r\n />\r\n );\r\n }\r\n\r\n // The list finished downloading but the view hasn't updated yet\r\n const { files, directories } = location!.type as API.DirectoryType;\r\n if (files !== 0 || directories !== 0) {\r\n return <Loader text={translate('Updating view')} />;\r\n }\r\n\r\n // The directory was changed but the download state hasn't changed yet\r\n if (!location!.complete) {\r\n return <Loader text={translate('Preparing download')} />;\r\n }\r\n\r\n return (\r\n <Message\r\n title={translate('No content to display')}\r\n description={translate('The directory is empty')}\r\n />\r\n );\r\n };\r\n\r\n const getCellCaption: FileDownloadCellCaptionGetter = (cellData, rowDataGetter) => {\r\n if (rowDataGetter().type.id === 'directory') {\r\n const onClick = () => onClickDirectory(filelist.location!.path + cellData + '/');\r\n return <LinkButton caption={cellData} onClick={onClick} />;\r\n }\r\n\r\n return cellData;\r\n };\r\n\r\n // const { session } = this.props;\r\n const sessionStore = useSessionStore();\r\n return (\r\n <>\r\n <VirtualTable\r\n emptyRowsNodeGetter={emptyRowsNodeGetter}\r\n rowClassNameGetter={rowClassNameGetter}\r\n store={FilelistViewStore}\r\n entityId={filelist.id}\r\n viewId={filelist.location!.path}\r\n sessionStore={sessionStore.filelists}\r\n moduleId={UI.Modules.FILELISTS}\r\n textFilterProps={{\r\n autoFocus: true,\r\n }}\r\n >\r\n <Column\r\n name=\"Name\"\r\n width={200}\r\n columnKey=\"name\"\r\n cell={<NameCell captionGetter={getCellCaption} filelist={filelist} />}\r\n flexGrow={8}\r\n />\r\n <Column\r\n name=\"Size\"\r\n width={60}\r\n columnKey=\"size\"\r\n cell={<SizeCell />}\r\n flexGrow={1}\r\n />\r\n <Column name=\"Type\" width={70} columnKey=\"type\" flexGrow={1} hideWidth={500} />\r\n <Column\r\n name=\"Last modified\"\r\n width={80}\r\n columnKey=\"time\"\r\n cell={<DurationCell />}\r\n flexGrow={1}\r\n />\r\n </VirtualTable>\r\n <FilelistItemInfoDialog filelist={filelist} />\r\n </>\r\n );\r\n};\r\n\r\nexport default FilelistItemTable;\r\n","import * as React from 'react';\r\n\r\nimport BrowserBar from '@/components/browserbar/BrowserBar';\r\nimport { ActionMenu, DownloadMenu } from '@/components/action-menu';\r\n\r\nimport DownloadDialog from '@/components/download/DownloadDialog';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { FilelistItemGetter } from './item-info-dialog';\r\nimport FilelistItemTable from './FilelistItemTable';\r\nimport { filelistDownloadHandler } from '@/services/api/FilelistApi';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\nimport { Location, useBlocker } from 'react-router';\r\nimport { useSyncFilelistLocation } from '../effects/useSyncFilelistLocation';\r\nimport NotificationActions from '@/actions/NotificationActions';\r\nimport { FilelistItemActionMenu } from '@/actions/ui/filelist';\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n location: Location;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst ListBrowser: React.FC<ListBrowserProps> = (props) => {\r\n const { sessionT, filelist } = props;\r\n const [hasClickedDirectory, setHasClickedDirectory] = React.useState(false);\r\n\r\n const updateLocationState = useSyncFilelistLocation(props);\r\n\r\n const handleClickDirectory = (path: string) => {\r\n if (!hasClickedDirectory) {\r\n setHasClickedDirectory(true);\r\n }\r\n\r\n updateLocationState(path, false);\r\n };\r\n\r\n useBlocker(({ currentLocation, nextLocation, historyAction }) => {\r\n if (\r\n historyAction === 'POP' &&\r\n hasClickedDirectory &&\r\n nextLocation.pathname !== currentLocation.pathname\r\n ) {\r\n setHasClickedDirectory(false);\r\n NotificationActions.info({\r\n title: sessionT.t('confirmLeave', 'Confirm action'),\r\n message: sessionT.t(\r\n 'confirmLeaveDesc',\r\n 'Click the back button again to leave this filelist',\r\n ),\r\n });\r\n return true;\r\n }\r\n\r\n return false;\r\n });\r\n\r\n const getCurrentDirectory = () => {\r\n return filelist.location;\r\n };\r\n\r\n const selectedNameFormatter = (caption: React.ReactNode) => {\r\n return (\r\n <DownloadMenu\r\n caption={caption}\r\n user={filelist.user}\r\n itemInfoGetter={getCurrentDirectory}\r\n downloadHandler={filelistDownloadHandler}\r\n contextElement=\".session-container\"\r\n entity={filelist}\r\n remoteMenuId={MenuConstants.FILELIST_ITEM}\r\n >\r\n <ActionMenu\r\n itemData={filelist.location}\r\n actions={FilelistItemActionMenu}\r\n entity={filelist}\r\n />\r\n </DownloadMenu>\r\n );\r\n };\r\n\r\n const userGetter = () => {\r\n return filelist.user;\r\n };\r\n\r\n const filelistItemFetcher = FilelistItemGetter(filelist);\r\n\r\n return (\r\n <div className=\"browser\">\r\n <BrowserBar\r\n path={filelist.location!.path}\r\n separator=\"/\"\r\n rootPath=\"/\"\r\n rootName={sessionT.translate('Root')}\r\n itemClickHandler={handleClickDirectory}\r\n selectedNameFormatter={selectedNameFormatter}\r\n // Just to make sure that the bar gets re-rendered when the switching to a different session (due to dropdown)\r\n entityId={filelist.id}\r\n />\r\n <FilelistItemTable\r\n filelist={filelist}\r\n sessionT={sessionT}\r\n onClickDirectory={handleClickDirectory}\r\n />\r\n <DownloadDialog\r\n downloadHandler={filelistDownloadHandler}\r\n itemDataGetter={filelistItemFetcher}\r\n userGetter={userGetter}\r\n sessionItem={filelist}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport default ListBrowser;\r\n","import * as React from 'react';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { changeFilelistDirectory } from '@/services/api/FilelistApi';\r\nimport { runBackgroundSocketAction } from '@/utils/ActionUtils';\r\nimport { Location, useNavigate } from 'react-router';\r\nimport { useSocket } from '@/context/SocketContext';\r\n\r\nexport type FilelistLocationState = { directory: string } | undefined;\r\n\r\ninterface ListBrowserProps {\r\n filelist: API.FilelistSession;\r\n location: Location;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\n// Keeps the current location in sync with the backend\r\nexport const useSyncFilelistLocation = ({\r\n filelist,\r\n location,\r\n sessionT,\r\n}: ListBrowserProps) => {\r\n const navigate = useNavigate();\r\n const socket = useSocket();\r\n\r\n const apiSendChangeDirectory = (directory: string) => {\r\n runBackgroundSocketAction(\r\n () => changeFilelistDirectory(filelist, directory, socket),\r\n sessionT.plainT,\r\n );\r\n };\r\n\r\n const updateLocationState = (directory: string, replace: boolean) => {\r\n const locationState = location.state as FilelistLocationState;\r\n if (directory === locationState?.directory) {\r\n return;\r\n }\r\n\r\n // Handle it through location state data\r\n // as we also handle history navigation changes\r\n const newState: FilelistLocationState = {\r\n directory,\r\n };\r\n\r\n navigate(location.pathname, {\r\n state: newState,\r\n replace,\r\n });\r\n };\r\n\r\n // Handler for directory changes received from the API\r\n React.useEffect(() => {\r\n const locationState = location.state as FilelistLocationState;\r\n\r\n if (!locationState) {\r\n // Initial mount\r\n updateLocationState(filelist.location!.path, true);\r\n return;\r\n }\r\n\r\n // Nothing has changed?\r\n if (locationState.directory === filelist.location!.path) {\r\n return;\r\n }\r\n\r\n // Change initiated by another session/GUI, update our location\r\n updateLocationState(filelist.location!.path, true);\r\n }, [filelist.location?.path]);\r\n\r\n // Handler for own changes\r\n React.useEffect(() => {\r\n const locationState = location.state as FilelistLocationState;\r\n if (!locationState) {\r\n // Initial mount, handled by the previous useEffect\r\n return;\r\n }\r\n\r\n const directory = locationState.directory;\r\n if (directory === filelist.location!.path) {\r\n return;\r\n }\r\n\r\n // It's our change\r\n if (directory) {\r\n apiSendChangeDirectory(directory);\r\n }\r\n }, [(location.state as FilelistLocationState)?.directory]);\r\n\r\n return updateLocationState;\r\n};\r\n","import FilelistFooter from '@/routes/Sidebar/routes/Filelists/components/FilelistFooter';\r\n\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport classNames from 'classnames';\r\nimport ListBrowser from './ListBrowser';\r\nimport { SessionChildProps } from '@/routes/Sidebar/components/types';\r\nimport { useActiveSession } from '@/effects/ActiveSessionEffect';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { FilelistStoreSelector } from '@/stores/session/filelistSlice';\r\n\r\ntype FilelistSessionProps = SessionChildProps<\r\n API.FilelistSession,\r\n UI.EmptyObject,\r\n UI.EmptyObject\r\n>;\r\n\r\nconst FilelistSession: React.FC<FilelistSessionProps> = ({\r\n sessionItem,\r\n sessionT,\r\n location: routerLocation,\r\n}) => {\r\n useActiveSession(sessionItem, FilelistAPIActions, FilelistStoreSelector);\r\n\r\n const { user, location: listLocation, state } = sessionItem;\r\n\r\n const isOwnList = user.flags.includes('self');\r\n const className = classNames('filelist session', { self: isOwnList });\r\n if (user.flags.includes('offline') && !isOwnList) {\r\n return (\r\n <div className={className}>\r\n <Message\r\n title={sessionT.t('userOffline', 'User offline')}\r\n description={sessionT.t(\r\n 'userOfflineDesc',\r\n 'You will be able to continue browsing when the user comes back online',\r\n )}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n if ((state.id !== 'loaded' && state.id !== 'download_failed') || !listLocation) {\r\n return (\r\n <div className={className}>\r\n <Loader text={state.str} />\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className={className}>\r\n <ListBrowser location={routerLocation} filelist={sessionItem} sessionT={sessionT} />\r\n\r\n <FilelistFooter filelist={sessionItem} sessionT={sessionT} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FilelistSession;\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport SessionLayout from '@/routes/Sidebar/components/SessionLayout';\r\nimport UserItemHandlerDecorator from '@/routes/Sidebar/decorators/UserItemHandlerDecorator';\r\n\r\nimport FilelistNew from '@/routes/Sidebar/routes/Filelists/components/FilelistNew';\r\nimport FilelistSession from '@/routes/Sidebar/routes/Filelists/components/FilelistSession';\r\n\r\nimport '../style.css';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport {\r\n SessionProviderDecorator,\r\n SessionProviderDecoratorChildProps,\r\n} from '@/routes/Sidebar/decorators/SessionProviderDecorator';\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport { FilelistSessionActionMenu } from '@/actions/ui/filelist';\r\nimport { FilelistAPIActions } from '@/actions/store/FilelistActions';\r\nimport { FilelistStoreSelector } from '@/stores/session/filelistSlice';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\nconst UserItemHandler = UserItemHandlerDecorator(['message']);\r\nconst ItemHandler: UI.SessionInfoGetter<API.FilelistSession> = {\r\n itemLabelGetter() {\r\n return null;\r\n },\r\n\r\n itemNameGetter(session) {\r\n return session.share_profile\r\n ? session.share_profile.str\r\n : UserItemHandler.itemNameGetter(session);\r\n },\r\n\r\n itemStatusGetter(session) {\r\n return session.share_profile ? 'blue' : UserItemHandler.itemStatusGetter!(session);\r\n },\r\n\r\n itemHeaderTitleGetter(session, location, actionMenu) {\r\n return session.share_profile\r\n ? actionMenu\r\n : UserItemHandler.itemHeaderTitleGetter!(session, location, actionMenu);\r\n },\r\n\r\n itemHeaderDescriptionGetter(session) {\r\n return session.share_profile\r\n ? null\r\n : UserItemHandler.itemHeaderDescriptionGetter(session);\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return session.share_profile\r\n ? 'green server'\r\n : UserItemHandler.itemHeaderIconGetter(session);\r\n },\r\n};\r\n\r\nconst Filelists: React.FC<SessionProviderDecoratorChildProps<API.FilelistSession>> = (\r\n props,\r\n) => {\r\n const { params, sessionT, ...other } = props;\r\n return (\r\n <SessionLayout\r\n activeId={params.id}\r\n baseUrl=\"filelists\"\r\n newCaption={sessionT.t('new', 'Open filelist')}\r\n newDescription={sessionT.t('newDesc', 'Start browsing a new filelist')}\r\n newIcon={IconConstants.FILELISTS_PLAIN}\r\n disableSideMenu={true}\r\n editAccess={API.AccessEnum.FILELISTS_EDIT}\r\n uiActions={FilelistSessionActionMenu}\r\n sessionApi={FilelistAPIActions}\r\n sessionStoreSelector={FilelistStoreSelector}\r\n sessionItemLayout={FilelistSession}\r\n newLayout={FilelistNew}\r\n sessionT={sessionT}\r\n remoteMenuId={MenuConstants.FILELIST}\r\n {...ItemHandler}\r\n {...other}\r\n />\r\n );\r\n};\r\n\r\nexport default SessionProviderDecorator(\r\n Filelists,\r\n FilelistStoreSelector,\r\n UI.Modules.FILELISTS,\r\n);\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.fileitem.info.segment .dupe-paths .path {\n overflow-x: hidden;\n}\n\n.fileitem.info.segment .download.ui.dropdown {\n max-width: 150px;\n margin-top: 10px;\n}\n\n.fileitem.info.segment .title.column {\n margin-top: auto;\n margin-bottom: auto;\n}\n\n.fileitem.info.segment .value.column {\n word-break: break-all;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/components/file-item-info/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;AAClB;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,qBAAqB;AACvB\",\"sourcesContent\":[\".fileitem.info.segment .dupe-paths .path {\\n overflow-x: hidden;\\n}\\n\\n.fileitem.info.segment .download.ui.dropdown {\\n max-width: 150px;\\n margin-top: 10px;\\n}\\n\\n.fileitem.info.segment .title.column {\\n margin-top: auto;\\n margin-bottom: auto;\\n}\\n\\n.fileitem.info.segment .value.column {\\n word-break: break-all;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import ShareConstants from '@/constants/ShareConstants';\r\nimport { APISocket } from '@/services/SocketService';\r\n\r\nimport { uploadTempFile } from '../HttpService';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface AddTempShareResponse {\r\n magnet: string;\r\n}\r\n\r\ninterface TempFileData {\r\n file: File;\r\n hubUrl: string;\r\n cid?: string;\r\n}\r\n\r\nexport const shareTempFile = async (\r\n { file, hubUrl, cid }: TempFileData,\r\n { auth_token: authToken }: UI.AuthenticatedSession,\r\n socket: APISocket,\r\n): Promise<AddTempShareResponse> => {\r\n // eslint-disable-next-line no-useless-catch\r\n try {\r\n const fileId = await uploadTempFile(file, authToken);\r\n const res = await socket.post<AddTempShareResponse>(ShareConstants.TEMP_SHARES_URL, {\r\n name: file.name,\r\n file_id: fileId,\r\n hub_url: hubUrl,\r\n cid,\r\n });\r\n\r\n return res;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nexport const refresh = (incoming: boolean, socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_URL, {\r\n incoming,\r\n priority: API.RefreshPriorityTypeEnum.MANUAL,\r\n });\r\n};\r\n\r\nexport const refreshPaths = (paths: string[], socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_PATHS_URL, {\r\n paths,\r\n priority: API.RefreshPriorityTypeEnum.MANUAL,\r\n });\r\n};\r\n\r\nexport const refreshVirtual = (path: string, socket: APISocket) => {\r\n return socket.post(ShareConstants.REFRESH_VIRTUAL_URL, {\r\n path,\r\n });\r\n};\r\n\r\nexport const abortRefreshTask = (id: number, socket: APISocket) => {\r\n return socket.delete(`${ShareConstants.REFRESH_TASKS_URL}/${id}`);\r\n};\r\n","import * as React from 'react';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n} from '@/decorators/DataProviderDecorator';\r\nimport { useFormatter } from '@/context/FormatterContext';\r\n\r\nimport LayoutHeader from '@/components/semantic/LayoutHeader';\r\nimport { ListItem } from '@/components/semantic/List';\r\n\r\nimport HistoryConstants, { HistoryEntryEnum } from '@/constants/HistoryConstants';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport { translate, toI18nKey } from '@/utils/TranslationUtils';\r\nimport { useTranslation } from 'react-i18next';\r\n\r\ninterface RecentLayoutProps {\r\n // Title of the button\r\n entryIcon: string;\r\n\r\n // URL for fetching the recent entries\r\n entryType: HistoryEntryEnum;\r\n\r\n // Renders the recent entry title\r\n entryTitleRenderer: (entry: API.HistoryItem) => React.ReactNode;\r\n\r\n // Returns whether the recent entry is currently active\r\n hasSession: (entry: API.HistoryItem) => boolean;\r\n}\r\n\r\ninterface DataProps {\r\n entries: API.HistoryItem[];\r\n}\r\n\r\ntype Props = RecentLayoutProps & DataProps & DataProviderDecoratorChildProps;\r\n\r\nconst RecentLayout: React.FC<Props> = ({\r\n entries,\r\n entryTitleRenderer,\r\n hasSession,\r\n entryIcon,\r\n}) => {\r\n const { formatRelativeTime } = useFormatter();\r\n const { t } = useTranslation();\r\n if (entries.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className=\"recents\">\r\n <LayoutHeader title={translate('Recent sessions', t, UI.Modules.COMMON)} size=\"\" />\r\n <div className=\"ui relaxed divided list\">\r\n {entries.map((entry, index) => (\r\n <ListItem\r\n key={index}\r\n header={entryTitleRenderer(entry)}\r\n description={\r\n !!entry.last_opened &&\r\n t(toI18nKey('openedAgo', UI.Modules.COMMON), {\r\n defaultValue: 'Opened {{timeAgo}}',\r\n replace: {\r\n timeAgo: formatRelativeTime(entry.last_opened),\r\n },\r\n })\r\n }\r\n icon={(hasSession(entry) ? 'green ' : '') + entryIcon}\r\n />\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\nexport const getHistoryUrl = (entryType: HistoryEntryEnum) => {\r\n return `${HistoryConstants.SESSIONS_URL}/${entryType}/0`;\r\n};\r\n\r\nexport default DataProviderDecorator<RecentLayoutProps, DataProps>(\r\n //RedrawDecorator<Props>(RecentLayout),\r\n RecentLayout,\r\n {\r\n urls: {\r\n entries: ({ entryType }, socket) => socket.get(getHistoryUrl(entryType)),\r\n },\r\n },\r\n);\r\n","import * as React from 'react';\r\nimport { merge } from 'lodash';\r\n\r\nimport ShareProfileConstants from '@/constants/ShareProfileConstants';\r\n\r\nimport DataProviderDecorator, {\r\n DataProviderDecoratorChildProps,\r\n DataProviderDecoratorSettings,\r\n DataConverter,\r\n} from '@/decorators/DataProviderDecorator';\r\n\r\nimport * as API from '@/types/api';\r\n\r\ninterface ShareProfileDecoratorDataProps {\r\n profiles: API.ShareProfile[];\r\n}\r\n\r\nexport type ShareProfileDecoratorChildProps = DataProviderDecoratorChildProps &\r\n ShareProfileDecoratorDataProps;\r\n\r\nconst ShareProfileDecorator = function <PropsT extends object>(\r\n Component: React.ComponentType<PropsT & ShareProfileDecoratorChildProps>,\r\n listHidden: boolean,\r\n dataProviderDecoratorSettings?: DataProviderDecoratorSettings<\r\n PropsT,\r\n ShareProfileDecoratorDataProps\r\n >,\r\n) {\r\n const convertProfiles: DataConverter<PropsT> = (data: API.ShareProfile[], { t }) => {\r\n const profiles = data.filter(\r\n (p) => listHidden || p.id !== ShareProfileConstants.HIDDEN_PROFILE_ID,\r\n );\r\n\r\n return profiles;\r\n };\r\n\r\n return DataProviderDecorator<PropsT, ShareProfileDecoratorDataProps>(\r\n Component,\r\n merge(dataProviderDecoratorSettings, {\r\n urls: {\r\n profiles: ShareProfileConstants.PROFILES_URL,\r\n },\r\n dataConverters: {\r\n profiles: convertProfiles,\r\n },\r\n onSocketConnected: (addSocketListener, { refetchData }) => {\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_ADDED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_UPDATED,\r\n () => refetchData(),\r\n );\r\n addSocketListener(\r\n ShareProfileConstants.MODULE_URL,\r\n ShareProfileConstants.PROFILE_REMOVED,\r\n () => refetchData(),\r\n );\r\n },\r\n } as DataProviderDecoratorSettings<PropsT, ShareProfileDecoratorDataProps>),\r\n );\r\n};\r\n\r\nexport default ShareProfileDecorator;\r\n","const MODULE_URL = 'share_profiles';\nexport default {\n MODULE_URL: MODULE_URL,\n PROFILES_URL: MODULE_URL,\n\n PROFILE_ADDED: 'share_profile_added',\n PROFILE_UPDATED: 'share_profile_updated',\n PROFILE_REMOVED: 'share_profile_removed',\n\n HIDDEN_PROFILE_ID: 1,\n};\n","import { fetchData } from '@/utils/HttpUtils';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport const uploadTempFile = async (file: File, authToken: string): Promise<string> => {\r\n // eslint-disable-next-line no-useless-catch\r\n try {\r\n const res = await fetchData(`${getBasePath()}temp`, {\r\n method: 'POST',\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': authToken,\r\n\r\n Authorization: authToken,\r\n },\r\n body: file,\r\n });\r\n\r\n return res.headers.get('Location')!;\r\n } catch (e) {\r\n throw e;\r\n }\r\n};\r\n\r\nconst toCorsSafeUrl = (url: string) => {\r\n const proxyUrl = `${\r\n window.location.origin\r\n }${getBasePath()}proxy?url=${encodeURIComponent(url)}`;\r\n return proxyUrl;\r\n};\r\n\r\ninterface FetchDataOptions extends RequestInit {\r\n isJSON?: boolean;\r\n}\r\n\r\nexport const fetchCorsSafeData = async (\r\n url: string,\r\n session: UI.AuthenticatedSession,\r\n options: FetchDataOptions = { isJSON: true },\r\n) => {\r\n try {\r\n //console.log(`CORS HTTP request started (${url})`);\r\n\r\n const res = await fetchData(toCorsSafeUrl(url), {\r\n headers: {\r\n // https://github.com/airdcpp-web/airdcpp-webclient/issues/330\r\n 'X-Authorization': session.auth_token,\r\n\r\n // Temp workaround for people upgrading from versions < 2.7.0\r\n // If the new UI was loaded before restarting the app, a cache expiration time of\r\n // one year would have been set for \"Not found\" errors...\r\n 'Cache-Control': 'no-store, must-revalidate, max-age=0',\r\n },\r\n ...options,\r\n });\r\n\r\n const data = (await options.isJSON) ? res.json() : res.text();\r\n return data;\r\n } catch (e) {\r\n console.error(`CORS HTTP request failed (${url})`, e);\r\n throw e;\r\n }\r\n};\r\n","\n import API from \"!../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport { useFormatter } from '@/context/FormatterContext';\r\n\r\nimport { DownloadMenu } from '@/components/action-menu';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { useTranslation } from 'react-i18next';\r\nimport { translate } from '@/utils/TranslationUtils';\r\n\r\nimport './style.css';\r\nimport { Row, Grid } from '@/components/semantic/Grid';\r\n\r\nconst DupeStrings = {\r\n //[API.DupeEnum.NONE]: 'None',\r\n [API.DupeEnum.SHARE_PARTIAL]: 'Share (partial)',\r\n [API.DupeEnum.SHARE_FULL]: 'Share (full)',\r\n [API.DupeEnum.QUEUE_PARTIAL]: 'Queue (partial)',\r\n [API.DupeEnum.QUEUE_FULL]: 'Queue (full)',\r\n [API.DupeEnum.FINISHED_PARTIAL]: 'Finished (partial)',\r\n [API.DupeEnum.FINISHED_FULL]: 'Finished (full)',\r\n [API.DupeEnum.SHARE_QUEUE]: 'Share and queue',\r\n [API.DupeEnum.SHARE_FINISHED]: 'Share and finished',\r\n [API.DupeEnum.QUEUE_FINISHED]: 'Queue and finished',\r\n [API.DupeEnum.SHARE_QUEUE_FINISHED]: 'Share, queue and finished',\r\n};\r\n\r\nconst DupePaths: React.FC<{ paths: string[] }> = ({ paths }) => (\r\n <div className=\"dupe-paths\">\r\n {paths.map((path) => (\r\n <div key={path} className=\"path\">\r\n {path}\r\n </div>\r\n ))}\r\n </div>\r\n);\r\n\r\ninterface FileItemInfoGridProps {\r\n fileItem: UI.DownloadableItemInfo;\r\n user: API.HintedUser;\r\n downloadHandler: UI.DownloadHandler<UI.DownloadableItemInfo>;\r\n showPath?: boolean;\r\n sessionItem: UI.SessionItemBase;\r\n}\r\n\r\nconst FileItemInfoGrid: React.FC<FileItemInfoGridProps> = ({\r\n sessionItem,\r\n fileItem,\r\n user,\r\n downloadHandler,\r\n showPath = true,\r\n}) => {\r\n const { t } = useTranslation();\r\n const gridT = (text: string) => {\r\n return translate(text, t, UI.Modules.COMMON);\r\n };\r\n\r\n const { formatSize, formatRelativeTime } = useFormatter();\r\n return (\r\n <div className=\"ui fileitem info segment\">\r\n <Grid columns=\"two\" stackable={true}>\r\n <Row title={gridT('Name')} text={fileItem.name} />\r\n <Row title={gridT('Type/content')} text={fileItem.type.str} />\r\n <Row title={gridT('Size')} text={formatSize(fileItem.size, 2, true)} />\r\n <Row\r\n title={gridT('Last modified')}\r\n text={formatRelativeTime(fileItem.time || 0)}\r\n />\r\n {fileItem.type.id === 'file' && <Row title={gridT('TTH')} text={fileItem.tth} />}\r\n {!!fileItem.dupe && (\r\n <Row title={gridT('Dupe type')} text={gridT(DupeStrings[fileItem.dupe.id])} />\r\n )}\r\n {!!fileItem.dupe && (\r\n <Row\r\n title={gridT('Dupe paths')}\r\n text={<DupePaths paths={fileItem.dupe.paths} />}\r\n />\r\n )}\r\n {showPath && <Row title={gridT('Path')} text={fileItem.path} />}\r\n </Grid>\r\n\r\n <DownloadMenu\r\n caption={gridT('Actions...')}\r\n button={true}\r\n user={user}\r\n itemInfoGetter={() => fileItem}\r\n downloadHandler={downloadHandler}\r\n contextElement=\".ui.modal > .content\"\r\n entity={sessionItem}\r\n />\r\n </div>\r\n );\r\n};\r\n\r\nexport { FileItemInfoGrid };\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `#sidebar .virtual-table {\n flex: 1 100 100%;\n}\n\n.filelist.session .browser,\n.filelist.session .browser .virtual-table {\n height: calc(100% - 35px);\n}\n\n#mobile-layout .filelist.session .browser {\n height: 100%;\n}\n\n#mobile-layout .filelist.session .browser {\n height: calc(100% - 10px);\n}\n\n@media screen and (min-color-index: 0) and(-webkit-min-device-pixel-ratio:0) {\n /* Safari specific CSS */\n .filelist.session .browser {\n height: calc(100% - 95px);\n }\n\n #mobile-layout .filelist.session .browser {\n height: calc(100% - 60px);\n }\n}\n\n.filelist.session .browser .ui.segment {\n margin-bottom: 10px;\n}\n\n.filelist.session {\n max-height: 100%;\n overflow: hidden;\n margin-top: 10px;\n flex: 1 1 100%;\n}\n\n.session.new .profile.ui.dropdown {\n margin-top: 10px;\n color: gray;\n align-self: flex-end;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/routes/Filelists/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,gBAAgB;AAClB;;AAEA;;EAEE,yBAAyB;AAC3B;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,yBAAyB;AAC3B;;AAEA;EACE,wBAAwB;EACxB;IACE,yBAAyB;EAC3B;;EAEA;IACE,yBAAyB;EAC3B;AACF;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,gBAAgB;EAChB,gBAAgB;EAChB,gBAAgB;EAChB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,WAAW;EACX,oBAAoB;AACtB\",\"sourcesContent\":[\"#sidebar .virtual-table {\\n flex: 1 100 100%;\\n}\\n\\n.filelist.session .browser,\\n.filelist.session .browser .virtual-table {\\n height: calc(100% - 35px);\\n}\\n\\n#mobile-layout .filelist.session .browser {\\n height: 100%;\\n}\\n\\n#mobile-layout .filelist.session .browser {\\n height: calc(100% - 10px);\\n}\\n\\n@media screen and (min-color-index: 0) and(-webkit-min-device-pixel-ratio:0) {\\n /* Safari specific CSS */\\n .filelist.session .browser {\\n height: calc(100% - 95px);\\n }\\n\\n #mobile-layout .filelist.session .browser {\\n height: calc(100% - 60px);\\n }\\n}\\n\\n.filelist.session .browser .ui.segment {\\n margin-bottom: 10px;\\n}\\n\\n.filelist.session {\\n max-height: 100%;\\n overflow: hidden;\\n margin-top: 10px;\\n flex: 1 1 100%;\\n}\\n\\n.session.new .profile.ui.dropdown {\\n margin-top: 10px;\\n color: gray;\\n align-self: flex-end;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n"],"names":["formatProfileNameWithSize","profile","formatSize","str","id","HIDDEN_PROFILE_ID","size","profileToEnumValue","formatter","name","itemMenuIds","itemNameGetter","session","user","nicks","itemStatusGetter","flags","itemHeaderDescriptionGetter","hub_names","itemHeaderIconGetter","itemHeaderTitleGetter","location","actionMenu","ids","remoteMenuId","HINTED_USER","ShareProfileDecorator","sessionT","profiles","onProfileChanged","Dropdown","className","caption","translate","triggerIcon","map","MenuItemLink","onClick","navigate","sessionStore","socket","createSessionProps","t","plainT","handleSubmit","createRemoteSession","onChange","offlineMessage","isClearable","autoFocus","shareProfileId","initCreateLocalSession","RecentLayout","entryType","FILELIST","hasSession","entry","filelists","getSession","cid","entryTitleRenderer","description","LinkButton","_","entryIcon","IconConstants","FILELISTS_PLAIN","filelist","locationText","type","length","SessionFooter","label","text","total_size","FilelistItemGetter","itemId","get","FilelistConstants","MODULE_URL","FilelistItemInfoDialog","Component","render","fileItem","this","props","RouteModal","title","closable","icon","FileIcon","typeInfo","fullHeight","DownloadDialog","downloadHandler","itemDataGetter","userGetter","sessionItem","displayName","Decorated","ModalRouteDecorator","DataProviderDecorator","urls","params","_viewName","VIEW_ID","_apiUrl","SESSIONS_URL","mixins","ViewStoreMixin","FilelistItemActions","reloadDirectory","access","FILELISTS_VIEW","RELOAD","filter","data","entity","partial_list","isPartialList","itemData","isDirectory","handler","item","post","list_path","path","reload","refreshShare","SETTINGS_EDIT","REFRESH_COLORED","includes","details","DETAILS","isRoot","FilelistItemActionMenu","moduleData","moduleId","FILELISTS","subId","actions","FilelistSessionActions","remove","FILELISTS_EDIT","FilelistSessionActionMenu","NameCell","rowDataGetter","captionGetter","other","MenuConstants","FILELIST_ITEM","onClickDirectory","VirtualTable","emptyRowsNodeGetter","state","Message","ERROR","files","directories","Loader","complete","rowClassNameGetter","rowData","dupe","store","FilelistViewStore","entityId","viewId","textFilterProps","width","columnKey","cell","cellData","flexGrow","hideWidth","hasClickedDirectory","setHasClickedDirectory","updateLocationState","directory","replace","locationState","newState","pathname","apiSendChangeDirectory","useSyncFilelistLocation","handleClickDirectory","currentLocation","nextLocation","historyAction","NotificationActions","info","message","getCurrentDirectory","filelistItemFetcher","BrowserBar","separator","rootPath","rootName","itemClickHandler","selectedNameFormatter","itemInfoGetter","contextElement","routerLocation","listLocation","isOwnList","self","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","UserItemHandler","UserItemHandlerDecorator","ItemHandler","itemLabelGetter","share_profile","SessionProviderDecorator","SessionLayout","activeId","baseUrl","newCaption","newDescription","newIcon","disableSideMenu","editAccess","uiActions","sessionApi","sessionStoreSelector","sessionItemLayout","newLayout","___CSS_LOADER_EXPORT___","push","module","shareTempFile","file","hubUrl","auth_token","authToken","fileId","TEMP_SHARES_URL","file_id","hub_url","e","refreshPaths","paths","REFRESH_PATHS_URL","priority","MANUAL","refreshVirtual","REFRESH_VIRTUAL_URL","abortRefreshTask","delete","REFRESH_TASKS_URL","entries","formatRelativeTime","COMMON","index","header","last_opened","defaultValue","timeAgo","getHistoryUrl","listHidden","dataProviderDecoratorSettings","merge","PROFILES_URL","dataConverters","p","onSocketConnected","addSocketListener","refetchData","PROFILE_ADDED","PROFILE_UPDATED","PROFILE_REMOVED","uploadTempFile","getBasePath","method","headers","Authorization","body","fetchCorsSafeData","url","isJSON","res","window","origin","encodeURIComponent","toCorsSafeUrl","json","console","error","DupeStrings","SHARE_PARTIAL","SHARE_FULL","QUEUE_PARTIAL","QUEUE_FULL","FINISHED_PARTIAL","FINISHED_FULL","SHARE_QUEUE","SHARE_FINISHED","QUEUE_FINISHED","SHARE_QUEUE_FINISHED","DupePaths","FileItemInfoGrid","showPath","gridT","Grid","columns","stackable","time","tth","button"],"sourceRoot":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[664],{40358:(e,n,t)=>{t.r(n),t.d(n,{default:()=>se});var s=t(74848),i=t(96540),o=t(91950),r=t(5945),a=t(32728),l=t(46942),c=t.n(l),d=t(4425),u=t(99347),m=t(80783),A=t(53632),f=t(74416),p=t(38453),h=t(8098);const x=(0,A.A)(({item:e,sessionT:n})=>{const{formatRelativeTime:t}=(0,f.k)();if((0,h.vU)())return null;const i=e.download_state;return(0,s.jsx)(p.q,{children:(0,s.jsx)(p.J,{label:n.translate(i?"Downloaded":"Opened"),text:t(i?i.time_finished:e.time_opened)})})});var E=t(68443),b=t(
|
|
2
|
-
//# sourceMappingURL=files.
|
|
1
|
+
"use strict";(self.webpackChunkairdcpp_webui=self.webpackChunkairdcpp_webui||[]).push([[664],{40358:(e,n,t)=>{t.r(n),t.d(n,{default:()=>se});var s=t(74848),i=t(96540),o=t(91950),r=t(5945),a=t(32728),l=t(46942),c=t.n(l),d=t(4425),u=t(99347),m=t(80783),A=t(53632),f=t(74416),p=t(38453),h=t(8098);const x=(0,A.A)(({item:e,sessionT:n})=>{const{formatRelativeTime:t}=(0,f.k)();if((0,h.vU)())return null;const i=e.download_state;return(0,s.jsx)(p.q,{children:(0,s.jsx)(p.J,{label:n.translate(i?"Downloaded":"Opened"),text:t(i?i.time_finished:e.time_opened)})})});var E=t(68443),b=t(13017),w=t(39364),y=t(51938),j=t(95093),v=t.n(j),g=t(41110);const C=e=>v().duration(v()().diff(v().unix(e.time_opened))).asMinutes()<=1,O=e=>(0,s.jsx)(y.ug,Object.assign({},e,{textGetter:()=>(0,g.F)(e.url).then(e=>e.text()).then(n=>(e.onReady(),n))})),_=e=>(0,s.jsx)(y.rI,Object.assign({autoPlay:C(e.item)},e)),I=e=>(0,s.jsx)(y.Ag,Object.assign({autoPlay:C(e.item)},e)),k=(e,n,t)=>`${e}view/${n}?auth_token=${t}`,B=(0,i.memo)(function({file:e,sessionT:n,scrollPositionHandler:t}){const{auth_token:i}=(0,w.wV)(),o=(0,b.$P)("/"),{scrollable:r,onScrollableContentReady:a}=(0,E.Lu)(t,e),l=(e=>{if(e.text)return O;switch(e.type.content_type){case"audio":return _;case"picture":return y.E5;case"video":return I}return null})(e);let c;return c=l?(0,s.jsx)(l,{item:e,url:k(o,e.tth,i),type:e.mime_type,extension:e.type.str,sessionT:n,onReady:a}):n.translate("Unsupported format"),(0,s.jsx)("article",{ref:r,className:"content",children:c})});var T=t(97145),R=t(62253),S=t(50592);const N=({sessionItem:e,sessionT:n})=>{(0,m.q)(e,R.z,S.E_);const t=(0,T.c7)(e=>e.viewFiles.scroll);return e.content_ready?(0,s.jsxs)("div",{className:c()("file session",e.type.str,e.type.content_type),children:[(0,s.jsx)(B,{file:e,sessionT:n,scrollPositionHandler:t}),(0,s.jsx)(x,{item:e,sessionT:n})]}):"download_failed"===e.download_state.id?(0,s.jsx)("div",{className:"file session",children:(0,s.jsx)(a.A,{icon:d.A.ERROR,title:n.translate("Download failed"),description:e.download_state.str})}):(0,s.jsx)(u.A,{text:e.download_state.str})};var D=t(86038),P=t(67749),W=t(78046),M=t(85899);const V={remove:(0,t(4112).R)(M.A.SESSIONS_URL,D.US.VIEW_FILE_EDIT)},F={moduleData:{moduleId:P.KV.VIEWED_FILES},actions:V};var L=t(85072),U=t.n(L),H=t(97825),G=t.n(H),K=t(77659),z=t.n(K),$=t(55056),Y=t.n($),q=t(10540),Z=t.n(q),J=t(41113),Q=t.n(J),X=t(69865),ee={};ee.styleTagTransform=Q(),ee.setAttributes=Y(),ee.insert=z().bind(null,"head"),ee.domAPI=G(),ee.insertStyleElement=Z(),U()(X.A,ee),X.A&&X.A.locals&&X.A.locals;var ne=t(39115);const te={itemNameGetter:e=>e.name,itemLabelGetter:()=>null,itemHeaderDescriptionGetter:()=>null,itemHeaderIconGetter:e=>(0,s.jsx)(r.A,{typeInfo:e.type})},se=(0,W.Z)(e=>{const{params:n,sessionT:t}=e,i=function(e,n){var t={};for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&n.indexOf(s)<0&&(t[s]=e[s]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(s=Object.getOwnPropertySymbols(e);i<s.length;i++)n.indexOf(s[i])<0&&Object.prototype.propertyIsEnumerable.call(e,s[i])&&(t[s[i]]=e[s[i]])}return t}(e,["params","sessionT"]);return 0===e.items.length?(0,s.jsx)(a.A,{title:t.t("noFiles","No files to view"),description:t.t("noFilesDesc","You may open text or media files to be viewed here from search or filelists")}):(0,s.jsx)(o.A,Object.assign({activeId:n.id,baseUrl:"files",disableSideMenu:!0,editAccess:D.US.VIEW_FILE_EDIT,uiActions:F,sessionApi:R.z,sessionStoreSelector:S.E_,sessionItemLayout:N,sessionT:t,remoteMenuId:ne.Ay.VIEW_FILE},te,i))},S.E_,P.KV.VIEWED_FILES)},51938:(e,n,t)=>{t.d(n,{rI:()=>r,E5:()=>a,ug:()=>f,Ag:()=>p});var s=t(74848),i=t(96540);function o(e){return({url:n,autoPlay:t})=>{const[o,r]=i.useState(null),a=i.useRef(null);if(i.useEffect(()=>{a.current&&a.current.load(),r(null)},[n]),o)return(0,s.jsx)("div",{children:o});const l={onError:e=>{r((e=>{const n=e.target.error;switch(n.code){case n.MEDIA_ERR_NETWORK:return"A network error caused the media download to fail";case n.MEDIA_ERR_DECODE:return"The media playback was aborted due to a corruption problem or because the media used features your browser did not support";case n.MEDIA_ERR_SRC_NOT_SUPPORTED:return"The media could not be loaded, either because the file was not found, network failed or because the format is not supported by your browser";default:return"An unknown media error occurred"}})(e))},autoPlay:t,controls:!0,src:n};return(0,s.jsx)(e,{mediaRef:a,mediaProps:l,url:n})}}const r=o(({mediaRef:e,mediaProps:n})=>(0,s.jsx)("audio",Object.assign({ref:e,style:{maxWidth:"100%",maxHeight:"100%"}},n,{children:(0,s.jsx)("track",{kind:"captions"})}))),a=({url:e})=>(0,s.jsx)("img",{src:e,style:{maxWidth:"100%",maxHeight:"100%"}});var l=t(62048),c=t(32728),d=t(67749),u=t(42695),m=t(32389),A=t(99347);const f=({textGetter:e,url:n})=>{const[t,o]=(0,i.useState)(null),[r,a]=(0,i.useState)(null),{t:f}=(0,m.Bd)();return(0,i.useEffect)(()=>(e().then(o).catch(a),()=>{o(null),a(null)}),[n]),t?(0,s.jsx)("pre",{children:(0,s.jsx)(l.PW,{text:t})}):r?(0,s.jsx)(c.A,{title:(0,u.Tl)("Failed to fetch content",f,d.KV.COMMON),description:r.message}):(0,s.jsx)(A.A,{})},p=o(({mediaRef:e,mediaProps:n})=>(0,s.jsx)("video",Object.assign({ref:e,style:{maxWidth:"100%",maxHeight:"100%"}},n,{children:(0,s.jsx)("track",{kind:"captions"})})))},53632:(e,n,t)=>{t.d(n,{A:()=>o});var s=t(74848),i=t(96540);function o(e,n=60){class t extends i.Component{constructor(){super(...arguments),this.scheduleComponentRefresh=()=>{this.redrawTimeout=window.setTimeout(()=>{this.forceUpdate(),this.scheduleComponentRefresh()},1e3*n)}}componentDidMount(){this.scheduleComponentRefresh()}componentWillUnmount(){clearTimeout(this.redrawTimeout)}render(){return(0,s.jsx)(e,Object.assign({},this.props))}}return t}},69865:(e,n,t)=>{t.d(n,{A:()=>a});var s=t(71354),i=t.n(s),o=t(76314),r=t.n(o)()(i());r.push([e.id,".file.session {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n max-width: 100%;\n margin-top: 10px;\n}\n\n.file.session .content {\n flex: 1;\n overflow: auto;\n}\n\n.file.session .content pre {\n overflow: initial;\n}\n\n.file.session.nfo .file-content pre {\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\n font-size: 11px;\n line-height: 12px;\n padding: 3px;\n margin: 0px;\n}\n\n.file.session img,\n.file.session video {\n max-width: 100%;\n max-height: 99%;\n}\n\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\n:-webkit-full-screen-ancestor:not(iframe) {\n max-width: inherit !important;\n overflow-x: initial;\n}\n\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\n visibility: hidden;\n}\n","",{version:3,sources:["webpack://./src/routes/Sidebar/routes/Files/style.css"],names:[],mappings:"AAAA;EACE,cAAc;EACd,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;AAClB;;AAEA;EACE,OAAO;EACP,cAAc;AAChB;;AAEA;EACE,iBAAiB;AACnB;;AAEA;EACE,yDAAyD;EACzD,eAAe;EACf,iBAAiB;EACjB,YAAY;EACZ,WAAW;AACb;;AAEA;;EAEE,eAAe;EACf,eAAe;AACjB;;AAEA,8EAA8E;AAC9E;EACE,6BAA6B;EAC7B,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;AACpB",sourcesContent:[".file.session {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n max-width: 100%;\n margin-top: 10px;\n}\n\n.file.session .content {\n flex: 1;\n overflow: auto;\n}\n\n.file.session .content pre {\n overflow: initial;\n}\n\n.file.session.nfo .file-content pre {\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\n font-size: 11px;\n line-height: 12px;\n padding: 3px;\n margin: 0px;\n}\n\n.file.session img,\n.file.session video {\n max-width: 100%;\n max-height: 99%;\n}\n\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\n:-webkit-full-screen-ancestor:not(iframe) {\n max-width: inherit !important;\n overflow-x: initial;\n}\n\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\n visibility: hidden;\n}\n"],sourceRoot:""}]);const a=r},73070:(e,n,t)=>{t.d(n,{Y9:()=>u,fI:()=>d,xA:()=>m});var s=t(74848),i=(t(96540),t(46942)),o=t.n(i),r=t(32389),a=t(42695),l=t(67749);const c=e=>e||(0,s.jsx)(r.x6,{i18nKey:(0,a.j2)("na",l.KV.COMMON),children:"N/A"}),d=({title:e,text:n,className:t,titleWidth:i="four",noText:r})=>(0,s.jsxs)("div",{className:o()("ui row",t),children:[(0,s.jsx)("div",{className:o()(r?"sixteen":i,"wide column title"),children:(0,s.jsx)("div",{className:"ui tiny header",style:{overflow:"hidden"},children:e})}),!r&&(0,s.jsx)("div",{className:"column value",children:c(n)})]}),u=({title:e})=>(0,s.jsx)("div",{className:"ui row",children:(0,s.jsx)("div",{className:"sixteen wide column",children:(0,s.jsx)("div",{className:"ui blue section header",children:e})})}),m=e=>{var{className:n,children:t,columns:i,stackable:r}=e,a=function(e,n){var t={};for(var s in e)Object.prototype.hasOwnProperty.call(e,s)&&n.indexOf(s)<0&&(t[s]=e[s]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(s=Object.getOwnPropertySymbols(e);i<s.length;i++)n.indexOf(s[i])<0&&Object.prototype.propertyIsEnumerable.call(e,s[i])&&(t[s[i]]=e[s[i]])}return t}(e,["className","children","columns","stackable"]);return(0,s.jsx)("div",Object.assign({className:o()("ui grid",{[`${i} column`]:!!i},{stackable:r},n)},a,{children:t}))}}}]);
|
|
2
|
+
//# sourceMappingURL=files.64f72b3869667e0d4c7e.chunk.js.map
|
|
Binary file
|
package/dist/js/{files.168b9574438986003ddd.chunk.js.map → files.64f72b3869667e0d4c7e.chunk.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"js/files.168b9574438986003ddd.chunk.js","mappings":"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","sources":["webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileViewerElement.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileContent.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileSession.tsx","webpack://airdcpp-webui/./src/actions/ui/viewed-file/ViewFileActions.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/style.css?5f3e","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/Files.tsx","webpack://airdcpp-webui/./src/components/file-preview/decorators/MediaFileDecorator.tsx","webpack://airdcpp-webui/./src/components/file-preview/AudioFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/ImageFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/TextFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/VideoFile.tsx","webpack://airdcpp-webui/./src/decorators/RedrawDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/style.css","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx"],"sourcesContent":["import * as React from 'react';\r\n\r\nimport RedrawDecorator from '@/decorators/RedrawDecorator';\r\nimport { useFormatter } from '@/context/FormatterContext';\r\nimport { FooterItem, SessionFooter } from '@/routes/Sidebar/components/SessionFooter';\r\nimport { usingMobileLayout } from '@/utils/BrowserUtils';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\ninterface FileFooterProps {\r\n item: API.ViewFile;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FileFooter: React.FC<FileFooterProps> = ({ item, sessionT }) => {\r\n const { formatRelativeTime } = useFormatter();\r\n if (usingMobileLayout()) {\r\n return null;\r\n }\r\n\r\n const downloadState = item.download_state;\r\n return (\r\n <SessionFooter>\r\n <FooterItem\r\n label={sessionT.translate(downloadState ? 'Downloaded' : 'Opened')}\r\n text={formatRelativeTime(\r\n downloadState ? downloadState.time_finished : item.time_opened,\r\n )}\r\n />\r\n </SessionFooter>\r\n );\r\n};\r\n\r\nexport default RedrawDecorator(FileFooter);\r\n","import * as React from 'react';\r\n\r\nimport { AudioFile, ImageFile, VideoFile, TextFile } from '@/components/file-preview';\r\n\r\nimport Moment from 'moment';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { fetchData } from '@/utils/HttpUtils';\r\n\r\ninterface ViewerElementProps {\r\n item: API.ViewFile;\r\n url: string;\r\n type: string;\r\n extension: string;\r\n sessionT: UI.ModuleTranslator;\r\n onReady: () => void;\r\n}\r\n\r\nconst useAutoPlay = (item: API.ViewFile) => {\r\n const diff = Moment.duration(Moment().diff(Moment.unix(item.time_opened)));\r\n return diff.asMinutes() <= 1;\r\n};\r\n\r\nconst TextViewerElement = (props: ViewerElementProps) => (\r\n <TextFile\r\n {...props}\r\n textGetter={() => {\r\n return fetchData(props.url)\r\n .then((data) => data.text())\r\n .then((text) => {\r\n props.onReady();\r\n return text;\r\n });\r\n }}\r\n />\r\n);\r\n\r\nconst AudioViewerElement = (props: ViewerElementProps) => (\r\n <AudioFile autoPlay={useAutoPlay(props.item)} {...props} />\r\n);\r\n\r\nconst VideoViewerElement = (props: ViewerElementProps) => (\r\n <VideoFile autoPlay={useAutoPlay(props.item)} {...props} />\r\n);\r\n\r\nexport const getFileViewerElement = (\r\n item: API.ViewFile,\r\n): React.ComponentType<ViewerElementProps> | null => {\r\n if (item.text) {\r\n return TextViewerElement;\r\n }\r\n\r\n switch (item.type.content_type) {\r\n case 'audio':\r\n return AudioViewerElement;\r\n case 'picture':\r\n return ImageFile;\r\n case 'video':\r\n return VideoViewerElement;\r\n default:\r\n }\r\n\r\n return null;\r\n};\r\n","import { memo } from 'react';\r\nimport * as React from 'react';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { useRestoreScroll } from '@/effects';\r\nimport { useHref } from 'react-router';\r\nimport { useSession } from '@/context/AppStoreContext';\r\nimport { getFileViewerElement } from './FileViewerElement';\r\n\r\nexport interface FileContentProps {\r\n file: API.ViewFile;\r\n sessionT: UI.ModuleTranslator;\r\n scrollPositionHandler: UI.ScrollHandler;\r\n}\r\nconst getUrl = (basePath: string, tth: string, authToken: string) => {\r\n return `${basePath}view/${tth}?auth_token=${authToken}`;\r\n};\r\n\r\nconst FileContent: React.FC<FileContentProps> = memo(function FileContent({\r\n file,\r\n sessionT,\r\n scrollPositionHandler,\r\n}) {\r\n const { auth_token: authToken } = useSession();\r\n const basePath = useHref('/');\r\n const { scrollable, onScrollableContentReady } = useRestoreScroll(\r\n scrollPositionHandler,\r\n file,\r\n );\r\n\r\n const ViewerElement = getFileViewerElement(file);\r\n\r\n let child;\r\n if (!ViewerElement) {\r\n child = sessionT.translate('Unsupported format');\r\n } else {\r\n child = (\r\n <ViewerElement\r\n item={file}\r\n url={getUrl(basePath, file.tth, authToken)}\r\n type={file.mime_type}\r\n extension={file.type.str}\r\n sessionT={sessionT}\r\n onReady={onScrollableContentReady}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <article ref={scrollable} className=\"content\">\r\n {child}\r\n </article>\r\n );\r\n});\r\n\r\nexport default FileContent;\r\n","import cx from 'classnames';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport { useActiveSession } from '@/effects/ActiveSessionEffect';\r\nimport FileFooter from '@/routes/Sidebar/routes/Files/components/FileFooter';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport FileContent from './FileContent';\r\nimport { SessionChildProps } from '@/routes/Sidebar/components/types';\r\nimport { useSessionStoreProperty } from '@/context/SessionStoreContext';\r\nimport { ViewFileAPIActions } from '@/actions/store/ViewFileActions';\r\nimport { ViewFileStoreSelector } from '@/stores/session/viewFileSlice';\r\n\r\nexport interface FileSessionProps\r\n extends SessionChildProps<API.ViewFile, UI.EmptyObject, UI.EmptyObject> {\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FileSession: React.FC<FileSessionProps> = ({ sessionItem, sessionT }) => {\r\n useActiveSession(sessionItem, ViewFileAPIActions, ViewFileStoreSelector);\r\n const scrollPositionHandler = useSessionStoreProperty(\r\n (state) => state.viewFiles.scroll,\r\n );\r\n\r\n if (!sessionItem.content_ready) {\r\n if (sessionItem.download_state!.id === 'download_failed') {\r\n return (\r\n <div className=\"file session\">\r\n <Message\r\n icon={IconConstants.ERROR}\r\n title={sessionT.translate('Download failed')}\r\n description={sessionItem.download_state!.str}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n return <Loader text={sessionItem.download_state!.str} />;\r\n }\r\n\r\n return (\r\n <div\r\n className={cx('file session', sessionItem.type.str, sessionItem.type.content_type)}\r\n >\r\n <FileContent\r\n file={sessionItem}\r\n sessionT={sessionT}\r\n scrollPositionHandler={scrollPositionHandler}\r\n />\r\n <FileFooter item={sessionItem} sessionT={sessionT} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FileSession;\r\n","import ViewFileConstants from '@/constants/ViewFileConstants';\r\n\r\nimport { BuildRemoveSessionAction } from '../decorators/SessionActionDecorator';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nconst ViewFileRemoveAction = BuildRemoveSessionAction(\r\n ViewFileConstants.SESSIONS_URL,\r\n API.AccessEnum.VIEW_FILE_EDIT,\r\n);\r\n\r\nconst ViewFileActions: UI.ActionListType<API.ViewFile> = {\r\n remove: ViewFileRemoveAction,\r\n};\r\n\r\nconst ViewFileActionModule = {\r\n moduleId: UI.Modules.VIEWED_FILES,\r\n};\r\n\r\nexport const ViewFileActionMenu = {\r\n moduleData: ViewFileActionModule,\r\n actions: ViewFileActions,\r\n};\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport SessionLayout from '@/routes/Sidebar/components/SessionLayout';\r\n\r\nimport FileIcon from '@/components/icon/FileIcon';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport FileSession from './FileSession';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport {\r\n SessionProviderDecoratorChildProps,\r\n SessionProviderDecorator,\r\n} from '@/routes/Sidebar/decorators/SessionProviderDecorator';\r\nimport { ViewFileActionMenu } from '@/actions/ui/viewed-file';\r\n\r\nimport { ViewFileAPIActions } from '@/actions/store/ViewFileActions';\r\nimport { ViewFileStoreSelector } from '@/stores/session/viewFileSlice';\r\n\r\nimport '../style.css';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\nconst ItemHandler: UI.SessionInfoGetter<API.ViewFile> = {\r\n itemNameGetter(session) {\r\n return session.name;\r\n },\r\n\r\n itemLabelGetter() {\r\n return null;\r\n },\r\n\r\n itemHeaderDescriptionGetter() {\r\n return null;\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return <FileIcon typeInfo={session.type} />;\r\n },\r\n};\r\n\r\nconst Files: React.FC<SessionProviderDecoratorChildProps<API.ViewFile>> = (props) => {\r\n const { params, sessionT, ...other } = props;\r\n if (props.items.length === 0) {\r\n return (\r\n <Message\r\n title={sessionT.t('noFiles', 'No files to view')}\r\n description={sessionT.t(\r\n 'noFilesDesc',\r\n 'You may open text or media files to be viewed here from search or filelists',\r\n )}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <SessionLayout\r\n activeId={params.id}\r\n baseUrl=\"files\"\r\n disableSideMenu={true}\r\n editAccess={API.AccessEnum.VIEW_FILE_EDIT}\r\n uiActions={ViewFileActionMenu}\r\n sessionApi={ViewFileAPIActions}\r\n sessionStoreSelector={ViewFileStoreSelector}\r\n sessionItemLayout={FileSession}\r\n sessionT={sessionT}\r\n remoteMenuId={MenuConstants.VIEW_FILE}\r\n {...ItemHandler}\r\n {...other}\r\n />\r\n );\r\n};\r\n\r\nexport default SessionProviderDecorator(\r\n Files,\r\n ViewFileStoreSelector,\r\n UI.Modules.VIEWED_FILES,\r\n);\r\n","import * as React from 'react';\n\nconst formatMediaError = (event: React.SyntheticEvent<HTMLMediaElement>) => {\n const error: MediaError = (event.target as any).error;\n switch (error.code) {\n case error.MEDIA_ERR_NETWORK:\n return 'A network error caused the media download to fail';\n case error.MEDIA_ERR_DECODE:\n // eslint-disable-next-line max-len\n return 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support';\n case error.MEDIA_ERR_SRC_NOT_SUPPORTED:\n // eslint-disable-next-line max-len\n return 'The media could not be loaded, either because the file was not found, network failed or because the format is not supported by your browser';\n default:\n return 'An unknown media error occurred';\n }\n};\n\nexport interface MediaFileDecoratorChildProps\n extends Pick<MediaFileDecoratorProps, 'url'> {\n mediaRef: React.Ref<HTMLMediaElement>;\n mediaProps: {\n onError: (event: React.SyntheticEvent<HTMLMediaElement>) => void;\n autoPlay: boolean;\n controls: boolean;\n src: string;\n };\n}\n\nexport interface MediaFileDecoratorProps {\n url: string;\n autoPlay: boolean;\n}\n\nexport default function (Component: React.ComponentType<MediaFileDecoratorChildProps>) {\n const MediaFileDecorator = ({ url, autoPlay }: MediaFileDecoratorProps) => {\n const [error, setError] = React.useState<null | string>(null);\n\n const mediaRef = React.useRef<HTMLMediaElement>(null);\n\n React.useEffect(() => {\n if (mediaRef.current) {\n mediaRef.current.load();\n }\n\n // Reset the error when switching between items\n setError(null);\n }, [url]);\n\n const onMediaError = (event: React.SyntheticEvent<HTMLMediaElement>) => {\n setError(formatMediaError(event));\n };\n\n if (error) {\n return <div>{error}</div>;\n }\n\n const mediaProps = {\n onError: onMediaError,\n autoPlay,\n controls: true,\n src: url,\n };\n\n return <Component mediaRef={mediaRef} mediaProps={mediaProps} url={url} />;\n };\n\n return MediaFileDecorator;\n}\n","import * as React from 'react';\n\nimport MediaFileDecorator, {\n MediaFileDecoratorChildProps,\n} from './decorators/MediaFileDecorator';\n\nconst AudioFile: React.FC<MediaFileDecoratorChildProps> = ({ mediaRef, mediaProps }) => (\n <audio\n ref={mediaRef}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n {...mediaProps}\n >\n <track kind=\"captions\" />\n </audio>\n);\n\nconst AudioFileDecorated = MediaFileDecorator(AudioFile);\n\nexport { AudioFileDecorated as AudioFile };\n","import * as React from 'react';\n\ninterface ImageFileProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n url: string;\n}\n\nconst ImageFile: React.FC<ImageFileProps> = ({ url }) => (\n <img\n src={url}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n);\n\nexport { ImageFile };\n","import { useEffect, useState } from 'react';\nimport * as React from 'react';\n\nimport { TextDecorator } from '@/components/text';\nimport Message from '@/components/semantic/Message';\n\nimport * as UI from '@/types/ui';\nimport { translate } from '@/utils/TranslationUtils';\nimport { useTranslation } from 'react-i18next';\nimport Loader from '@/components/semantic/Loader';\n\ninterface TextFileProps {\n textGetter: () => Promise<string>;\n url?: string;\n}\n\nconst TextFile: React.FC<TextFileProps> = ({ textGetter, url }) => {\n const [text, setText] = useState<string | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n const { t } = useTranslation();\n useEffect(() => {\n textGetter().then(setText).catch(setError);\n\n return () => {\n setText(null);\n setError(null);\n };\n }, [url]);\n\n if (!text) {\n if (error) {\n return (\n <Message\n title={translate('Failed to fetch content', t, UI.Modules.COMMON)}\n description={error.message}\n />\n );\n }\n\n return <Loader />;\n }\n\n return (\n <pre>\n <TextDecorator text={text} />\n </pre>\n );\n};\n\nexport { TextFile };\n","import * as React from 'react';\n\nimport MediaFileDecorator, {\n MediaFileDecoratorChildProps,\n} from './decorators/MediaFileDecorator';\n\nconst VideoFile: React.FC<MediaFileDecoratorChildProps> = ({ mediaRef, mediaProps }) => (\n <video\n ref={mediaRef as React.Ref<HTMLVideoElement>}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n {...mediaProps}\n >\n <track kind=\"captions\" />\n </video>\n);\n\nconst VideoFileDecorated = MediaFileDecorator(VideoFile);\n\nexport { VideoFileDecorated as VideoFile };\n","import * as React from 'react';\r\n\r\nexport default function <PropsT>(\r\n Component: React.ComponentType<PropsT>,\r\n redrawIntervalSeconds = 60,\r\n) {\r\n class RedrawDecorator extends React.Component<PropsT> {\r\n redrawTimeout: number | undefined;\r\n\r\n componentDidMount() {\r\n this.scheduleComponentRefresh();\r\n }\r\n\r\n componentWillUnmount() {\r\n clearTimeout(this.redrawTimeout);\r\n }\r\n\r\n scheduleComponentRefresh = () => {\r\n this.redrawTimeout = window.setTimeout(() => {\r\n this.forceUpdate();\r\n this.scheduleComponentRefresh();\r\n }, redrawIntervalSeconds * 1000);\r\n };\r\n\r\n render() {\r\n return <Component {...this.props} />;\r\n }\r\n }\r\n\r\n return RedrawDecorator;\r\n}\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.file.session {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n max-width: 100%;\n margin-top: 10px;\n}\n\n.file.session .content {\n flex: 1;\n overflow: auto;\n}\n\n.file.session .content pre {\n overflow: initial;\n}\n\n.file.session.nfo .file-content pre {\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\n font-size: 11px;\n line-height: 12px;\n padding: 3px;\n margin: 0px;\n}\n\n.file.session img,\n.file.session video {\n max-width: 100%;\n max-height: 99%;\n}\n\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\n:-webkit-full-screen-ancestor:not(iframe) {\n max-width: inherit !important;\n overflow-x: initial;\n}\n\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\n visibility: hidden;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/routes/Files/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,cAAc;EACd,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;AAClB;;AAEA;EACE,OAAO;EACP,cAAc;AAChB;;AAEA;EACE,iBAAiB;AACnB;;AAEA;EACE,yDAAyD;EACzD,eAAe;EACf,iBAAiB;EACjB,YAAY;EACZ,WAAW;AACb;;AAEA;;EAEE,eAAe;EACf,eAAe;AACjB;;AAEA,8EAA8E;AAC9E;EACE,6BAA6B;EAC7B,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;AACpB\",\"sourcesContent\":[\".file.session {\\n flex: 1 1 auto;\\n display: flex;\\n flex-direction: column;\\n max-height: 100%;\\n max-width: 100%;\\n margin-top: 10px;\\n}\\n\\n.file.session .content {\\n flex: 1;\\n overflow: auto;\\n}\\n\\n.file.session .content pre {\\n overflow: initial;\\n}\\n\\n.file.session.nfo .file-content pre {\\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\\n font-size: 11px;\\n line-height: 12px;\\n padding: 3px;\\n margin: 0px;\\n}\\n\\n.file.session img,\\n.file.session video {\\n max-width: 100%;\\n max-height: 99%;\\n}\\n\\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\\n:-webkit-full-screen-ancestor:not(iframe) {\\n max-width: inherit !important;\\n overflow-x: initial;\\n}\\n\\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\\n visibility: hidden;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from '@/utils/TranslationUtils';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n\r\n return <Trans i18nKey={toI18nKey('na', UI.Modules.COMMON)}>N/A</Trans>;\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({\r\n title,\r\n text,\r\n className,\r\n titleWidth = 'four',\r\n noText,\r\n}) => (\r\n <div className={classNames('ui row', className)}>\r\n <div className={classNames(noText ? 'sixteen' : titleWidth, 'wide column title')}>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n {title}\r\n </div>\r\n </div>\r\n {!noText && <div className=\"column value\">{formatText(text)}</div>}\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">{title}</div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({\r\n className,\r\n children,\r\n columns,\r\n stackable,\r\n ...other\r\n}) => (\r\n <div\r\n className={classNames(\r\n 'ui grid',\r\n //`${columns} column`,\r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className,\r\n )}\r\n {...other}\r\n >\r\n {children}\r\n </div>\r\n);\r\n"],"names":["RedrawDecorator","item","sessionT","formatRelativeTime","downloadState","download_state","SessionFooter","label","translate","text","time_finished","time_opened","useAutoPlay","diff","asMinutes","TextViewerElement","props","textGetter","url","then","data","onReady","AudioViewerElement","autoPlay","VideoViewerElement","getUrl","basePath","tth","authToken","memo","file","scrollPositionHandler","auth_token","scrollable","onScrollableContentReady","ViewerElement","type","content_type","getFileViewerElement","child","mime_type","extension","str","ref","className","sessionItem","state","viewFiles","scroll","content_ready","id","Message","icon","IconConstants","ERROR","title","description","Loader","remove","ViewFileConstants","SESSIONS_URL","VIEW_FILE_EDIT","ViewFileActionMenu","moduleData","moduleId","VIEWED_FILES","actions","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","ItemHandler","itemNameGetter","session","name","itemLabelGetter","itemHeaderDescriptionGetter","itemHeaderIconGetter","FileIcon","typeInfo","SessionProviderDecorator","params","other","items","length","t","SessionLayout","activeId","baseUrl","disableSideMenu","editAccess","uiActions","sessionApi","sessionStoreSelector","sessionItemLayout","remoteMenuId","MenuConstants","VIEW_FILE","Component","error","setError","mediaRef","current","load","mediaProps","onError","event","target","code","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","formatMediaError","controls","src","AudioFileDecorated","MediaFileDecorator","style","maxWidth","maxHeight","kind","ImageFile","TextFile","setText","useState","useEffect","catch","COMMON","message","VideoFileDecorated","redrawIntervalSeconds","scheduleComponentRefresh","this","redrawTimeout","window","setTimeout","forceUpdate","componentDidMount","componentWillUnmount","clearTimeout","render","___CSS_LOADER_EXPORT___","push","module","formatText","i18nKey","Row","titleWidth","noText","overflow","Header","Grid","children","columns","stackable"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"js/files.64f72b3869667e0d4c7e.chunk.js","mappings":"sSAeA,MAmBA,GAAe,EAAAA,EAAA,GAnB+B,EAAGC,OAAMC,eACrD,MAAM,mBAAEC,IAAuB,SAC/B,IAAI,UACF,OAAO,KAGT,MAAMC,EAAgBH,EAAKI,eAC3B,OACE,SAACC,EAAA,EAAa,WACZ,SAAC,IAAU,CACTC,MAAOL,EAASM,UAAUJ,EAAgB,aAAe,UACzDK,KAAMN,EACJC,EAAgBA,EAAcM,cAAgBT,EAAKU,mB,+ECP7D,MAAMC,EAAeX,GACN,aAAgB,MAASY,KAAK,SAAYZ,EAAKU,eAChDG,aAAe,EAGvBC,EAAqBC,IACzB,SAAC,KAAQ,iBACHA,EAAK,CACTC,WAAY,KACH,OAAUD,EAAME,KACpBC,KAAMC,GAASA,EAAKX,QACpBU,KAAMV,IACLO,EAAMK,UACCZ,OAMXa,EAAsBN,IAC1B,SAAC,KAAS,eAACO,SAAUX,EAAYI,EAAMf,OAAWe,IAG9CQ,EAAsBR,IAC1B,SAAC,KAAS,eAACO,SAAUX,EAAYI,EAAMf,OAAWe,IC5B9CS,EAAS,CAACC,EAAkBC,EAAaC,IACtC,GAAGF,SAAgBC,gBAAkBC,IAwC9C,GArCgD,IAAAC,MAAK,UAAqB,KACxEC,EAAI,SACJ5B,EAAQ,sBACR6B,IAEA,MAAQC,WAAYJ,IAAc,UAC5BF,GAAW,QAAQ,MACnB,WAAEO,EAAU,yBAAEC,IAA6B,QAC/CH,EACAD,GAGIK,EDe4B,CAClClC,IAEA,GAAIA,EAAKQ,KACP,OAAOM,EAGT,OAAQd,EAAKmC,KAAKC,cAChB,IAAK,QACH,OAAOf,EACT,IAAK,UACH,OAAO,KACT,IAAK,QACH,OAAOE,EAIX,OAAO,MChCec,CAAqBR,GAE3C,IAAIS,EAgBJ,OAZEA,EAHGJ,GAID,SAACA,EAAa,CACZlC,KAAM6B,EACNZ,IAAKO,EAAOC,EAAUI,EAAKH,IAAKC,GAChCQ,KAAMN,EAAKU,UACXC,UAAWX,EAAKM,KAAKM,IACrBxC,SAAUA,EACVmB,QAASa,IATLhC,EAASM,UAAU,uBAe3B,oBAASmC,IAAKV,EAAYW,UAAU,UAAS,SAC1CL,GAGP,G,qCChCA,MAoCA,EApCgD,EAAGM,cAAa3C,gBAC9D,OAAiB2C,EAAa,IAAoB,MAClD,MAAMd,GAAwB,QAC3Be,GAAUA,EAAMC,UAAUC,QAG7B,OAAKH,EAAYI,eAiBf,iBACEL,UAAW,IAAG,eAAgBC,EAAYT,KAAKM,IAAKG,EAAYT,KAAKC,cAAa,WAElF,SAAC,EAAW,CACVP,KAAMe,EACN3C,SAAUA,EACV6B,sBAAuBA,KAEzB,SAAC,EAAU,CAAC9B,KAAM4C,EAAa3C,SAAUA,OAxBJ,oBAAnC2C,EAAYxC,eAAgB6C,IAE5B,gBAAKN,UAAU,eAAc,UAC3B,SAACO,EAAA,EAAO,CACNC,KAAMC,EAAA,EAAcC,MACpBC,MAAOrD,EAASM,UAAU,mBAC1BgD,YAAaX,EAAYxC,eAAgBqC,SAM1C,SAACe,EAAA,EAAM,CAAChD,KAAMoC,EAAYxC,eAAgBqC,O,gDCnCrD,MAKM,EAAmD,CACvDgB,QAN2B,E,QAAA,GAC3BC,EAAA,EAAkBC,aAClB,KAAeC,iBAWJC,EAAqB,CAChCC,WAL2B,CAC3BC,SAAU,KAAWC,cAKrBC,QAAS,G,uICXPC,GAAU,CAAC,EAEfA,GAAQC,kBAAoB,IAC5BD,GAAQE,cAAgB,IACxBF,GAAQG,OAAS,SAAc,KAAM,QACrCH,GAAQI,OAAS,IACjBJ,GAAQK,mBAAqB,IAEhB,IAAI,IAASL,IAKJ,KAAW,IAAQM,QAAS,IAAQA,O,gBCD1D,MAAMC,GAAkD,CACtDC,eAAeC,GACNA,EAAQC,KAGjBC,gBAAe,IACN,KAGTC,4BAA2B,IAClB,KAGTC,qBAAqBJ,IACZ,SAACK,EAAA,EAAQ,CAACC,SAAUN,EAAQxC,QAoCvC,IAAe,EAAA+C,EAAA,GAhC4DnE,IACzE,MAAM,OAAEoE,EAAM,SAAElF,GAAuBc,EAAVqE,E,yUAAK,CAAKrE,EAAjC,uBACN,OAA2B,IAAvBA,EAAMsE,MAAMC,QAEZ,SAACpC,EAAA,EAAO,CACNI,MAAOrD,EAASsF,EAAE,UAAW,oBAC7BhC,YAAatD,EAASsF,EACpB,cACA,kFAON,SAACC,EAAA,EAAa,eACZC,SAAUN,EAAOlC,GACjByC,QAAQ,QACRC,iBAAiB,EACjBC,WAAY,KAAehC,eAC3BiC,UAAWhC,EACXiC,WAAY,IACZC,qBAAsB,KACtBC,kBAAmB,EACnB/F,SAAUA,EACVgG,aAAcC,GAAA,GAAcC,WACxB1B,GACAW,KAOR,KACA,KAAWpB,a,yFC1CE,SAAS,EAACoC,GAiCvB,MAhC2B,EAAGnF,MAAKK,eACjC,MAAO+E,EAAOC,GAAY,WAA8B,MAElDC,EAAW,SAA+B,MAehD,GAbA,YAAgB,KACVA,EAASC,SACXD,EAASC,QAAQC,OAInBH,EAAS,OACR,CAACrF,IAMAoF,EACF,OAAO,yBAAMA,IAGf,MAAMK,EAAa,CACjBC,QAToBC,IACpBN,EAhDmB,CAACM,IACxB,MAAMP,EAAqBO,EAAMC,OAAeR,MAChD,OAAQA,EAAMS,MACZ,KAAKT,EAAMU,kBACT,MAAO,oDACT,KAAKV,EAAMW,iBAET,MAAO,6HACT,KAAKX,EAAMY,4BAET,MAAO,8IACT,QACE,MAAO,oCAoCEC,CAAiBN,KAS1BtF,WACA6F,UAAU,EACVC,IAAKnG,GAGP,OAAO,SAACmF,EAAS,CAACG,SAAUA,EAAUG,WAAYA,EAAYzF,IAAKA,IAIvE,CC9DA,MAaMoG,EAAqBC,EAb+B,EAAGf,WAAUG,iBACrE,gCACEhE,IAAK6D,EACLgB,MAAO,CACLC,SAAU,OACVC,UAAW,SAETf,EAAU,WAEd,kBAAOgB,KAAK,iBCTVC,EAAsC,EAAG1G,UAC7C,gBACEmG,IAAKnG,EACLsG,MAAO,CACLC,SAAU,OACVC,UAAW,U,sECKjB,MAAMG,EAAoC,EAAG5G,aAAYC,UACvD,MAAOT,EAAMqH,IAAW,IAAAC,UAAwB,OACzCzB,EAAOC,IAAY,IAAAwB,UAAuB,OAE3C,EAAEvC,IAAM,UAUd,OATA,IAAAwC,WAAU,KACR/G,IAAaE,KAAK2G,GAASG,MAAM1B,GAE1B,KACLuB,EAAQ,MACRvB,EAAS,QAEV,CAACrF,IAECT,GAcH,0BACE,SAAC,KAAa,CAACA,KAAMA,MAdnB6F,GAEA,SAACnD,EAAA,EAAO,CACNI,OAAO,QAAU,0BAA2BiC,EAAG,KAAW0C,QAC1D1E,YAAa8C,EAAM6B,WAKlB,SAAC1E,EAAA,EAAM,KCrBZ2E,EAAqBb,EAb+B,EAAGf,WAAUG,iBACrE,gCACEhE,IAAK6D,EACLgB,MAAO,CACLC,SAAU,OACVC,UAAW,SAETf,EAAU,WAEd,kBAAOgB,KAAK,gB,6DCbD,SAAS,EACtBtB,EACAgC,EAAwB,IAExB,MAAMrI,UAAwB,YAA9B,c,oBAWE,KAAAsI,yBAA2B,KACzBC,KAAKC,cAAgBC,OAAOC,WAAW,KACrCH,KAAKI,cACLJ,KAAKD,4BACoB,IAAxBD,GAMP,CAlBE,iBAAAO,GACEL,KAAKD,0BACP,CAEA,oBAAAO,GACEC,aAAaP,KAAKC,cACpB,CASA,MAAAO,GACE,OAAO,SAAC1C,EAAS,iBAAKkC,KAAKvH,OAC7B,EAGF,OAAOhB,CACT,C,sEC3BIgJ,E,MAA0B,GAA4B,KAE1DA,EAAwBC,KAAK,CAACC,EAAOhG,GAAI,0yBAyCtC,GAAG,CAAC,QAAU,EAAE,QAAU,CAAC,yDAAyD,MAAQ,GAAG,SAAW,uTAAuT,eAAiB,CAAC,2yBAA2yB,WAAa,MAE9uC,S,qIChCA,MAAMiG,EAAc1I,GACZA,IAIC,SAAC,KAAK,CAAC2I,SAAS,QAAU,KAAM,KAAWlB,QAAO,iBAG9CmB,EAA0B,EACrC9F,QACA9C,OACAmC,YACA0G,aAAa,OACbC,aAEA,iBAAK3G,UAAW,IAAW,SAAUA,GAAU,WAC7C,gBAAKA,UAAW,IAAW2G,EAAS,UAAYD,EAAY,qBAAoB,UAC9E,gBAAK1G,UAAU,iBAAiB4E,MAAO,CAAEgC,SAAU,UAAU,SAC1DjG,OAGHgG,IAAU,gBAAK3G,UAAU,eAAc,SAAEuG,EAAW1I,QAQ7CgJ,EAAgC,EAAGlG,YAC9C,gBAAKX,UAAU,SAAQ,UACrB,gBAAKA,UAAU,sBAAqB,UAClC,gBAAKA,UAAU,yBAAwB,SAAEW,QAUlCmG,EAA6B,I,IAAA,UACxC9G,EAAS,SACT+G,EAAQ,QACRC,EAAO,UACPC,GAAS,EACNxE,E,yUAAK,GALgC,gDAMpC,OACJ,8BACEzC,UAAW,IACT,UAEA,CAAE,CAAC,GAAGgH,cAAqBA,GAC3B,CAAEC,UAAWA,GACbjH,IAEEyC,EAAK,UAERsE,K","sources":["webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileFooter.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileViewerElement.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileContent.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/FileSession.tsx","webpack://airdcpp-webui/./src/actions/ui/viewed-file/ViewFileActions.ts","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/style.css?5f3e","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/components/Files.tsx","webpack://airdcpp-webui/./src/components/file-preview/decorators/MediaFileDecorator.tsx","webpack://airdcpp-webui/./src/components/file-preview/AudioFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/ImageFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/TextFile.tsx","webpack://airdcpp-webui/./src/components/file-preview/VideoFile.tsx","webpack://airdcpp-webui/./src/decorators/RedrawDecorator.tsx","webpack://airdcpp-webui/./src/routes/Sidebar/routes/Files/style.css","webpack://airdcpp-webui/./src/components/semantic/Grid.tsx"],"sourcesContent":["import * as React from 'react';\r\n\r\nimport RedrawDecorator from '@/decorators/RedrawDecorator';\r\nimport { useFormatter } from '@/context/FormatterContext';\r\nimport { FooterItem, SessionFooter } from '@/routes/Sidebar/components/SessionFooter';\r\nimport { usingMobileLayout } from '@/utils/BrowserUtils';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\ninterface FileFooterProps {\r\n item: API.ViewFile;\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FileFooter: React.FC<FileFooterProps> = ({ item, sessionT }) => {\r\n const { formatRelativeTime } = useFormatter();\r\n if (usingMobileLayout()) {\r\n return null;\r\n }\r\n\r\n const downloadState = item.download_state;\r\n return (\r\n <SessionFooter>\r\n <FooterItem\r\n label={sessionT.translate(downloadState ? 'Downloaded' : 'Opened')}\r\n text={formatRelativeTime(\r\n downloadState ? downloadState.time_finished : item.time_opened,\r\n )}\r\n />\r\n </SessionFooter>\r\n );\r\n};\r\n\r\nexport default RedrawDecorator(FileFooter);\r\n","import * as React from 'react';\r\n\r\nimport { AudioFile, ImageFile, VideoFile, TextFile } from '@/components/file-preview';\r\n\r\nimport Moment from 'moment';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { fetchData } from '@/utils/HttpUtils';\r\n\r\ninterface ViewerElementProps {\r\n item: API.ViewFile;\r\n url: string;\r\n type: string;\r\n extension: string;\r\n sessionT: UI.ModuleTranslator;\r\n onReady: () => void;\r\n}\r\n\r\nconst useAutoPlay = (item: API.ViewFile) => {\r\n const diff = Moment.duration(Moment().diff(Moment.unix(item.time_opened)));\r\n return diff.asMinutes() <= 1;\r\n};\r\n\r\nconst TextViewerElement = (props: ViewerElementProps) => (\r\n <TextFile\r\n {...props}\r\n textGetter={() => {\r\n return fetchData(props.url)\r\n .then((data) => data.text())\r\n .then((text) => {\r\n props.onReady();\r\n return text;\r\n });\r\n }}\r\n />\r\n);\r\n\r\nconst AudioViewerElement = (props: ViewerElementProps) => (\r\n <AudioFile autoPlay={useAutoPlay(props.item)} {...props} />\r\n);\r\n\r\nconst VideoViewerElement = (props: ViewerElementProps) => (\r\n <VideoFile autoPlay={useAutoPlay(props.item)} {...props} />\r\n);\r\n\r\nexport const getFileViewerElement = (\r\n item: API.ViewFile,\r\n): React.ComponentType<ViewerElementProps> | null => {\r\n if (item.text) {\r\n return TextViewerElement;\r\n }\r\n\r\n switch (item.type.content_type) {\r\n case 'audio':\r\n return AudioViewerElement;\r\n case 'picture':\r\n return ImageFile;\r\n case 'video':\r\n return VideoViewerElement;\r\n default:\r\n }\r\n\r\n return null;\r\n};\r\n","import { memo } from 'react';\r\nimport * as React from 'react';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport { useRestoreScroll } from '@/effects';\r\nimport { useHref } from 'react-router';\r\nimport { useSession } from '@/context/AppStoreContext';\r\nimport { getFileViewerElement } from './FileViewerElement';\r\n\r\nexport interface FileContentProps {\r\n file: API.ViewFile;\r\n sessionT: UI.ModuleTranslator;\r\n scrollPositionHandler: UI.ScrollHandler;\r\n}\r\nconst getUrl = (basePath: string, tth: string, authToken: string) => {\r\n return `${basePath}view/${tth}?auth_token=${authToken}`;\r\n};\r\n\r\nconst FileContent: React.FC<FileContentProps> = memo(function FileContent({\r\n file,\r\n sessionT,\r\n scrollPositionHandler,\r\n}) {\r\n const { auth_token: authToken } = useSession();\r\n const basePath = useHref('/');\r\n const { scrollable, onScrollableContentReady } = useRestoreScroll(\r\n scrollPositionHandler,\r\n file,\r\n );\r\n\r\n const ViewerElement = getFileViewerElement(file);\r\n\r\n let child;\r\n if (!ViewerElement) {\r\n child = sessionT.translate('Unsupported format');\r\n } else {\r\n child = (\r\n <ViewerElement\r\n item={file}\r\n url={getUrl(basePath, file.tth, authToken)}\r\n type={file.mime_type}\r\n extension={file.type.str}\r\n sessionT={sessionT}\r\n onReady={onScrollableContentReady}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <article ref={scrollable} className=\"content\">\r\n {child}\r\n </article>\r\n );\r\n});\r\n\r\nexport default FileContent;\r\n","import cx from 'classnames';\r\n\r\nimport IconConstants from '@/constants/IconConstants';\r\nimport Loader from '@/components/semantic/Loader';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport { useActiveSession } from '@/effects/ActiveSessionEffect';\r\nimport FileFooter from '@/routes/Sidebar/routes/Files/components/FileFooter';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nimport FileContent from './FileContent';\r\nimport { SessionChildProps } from '@/routes/Sidebar/components/types';\r\nimport { useSessionStoreProperty } from '@/context/SessionStoreContext';\r\nimport { ViewFileAPIActions } from '@/actions/store/ViewFileActions';\r\nimport { ViewFileStoreSelector } from '@/stores/session/viewFileSlice';\r\n\r\nexport interface FileSessionProps\r\n extends SessionChildProps<API.ViewFile, UI.EmptyObject, UI.EmptyObject> {\r\n sessionT: UI.ModuleTranslator;\r\n}\r\n\r\nconst FileSession: React.FC<FileSessionProps> = ({ sessionItem, sessionT }) => {\r\n useActiveSession(sessionItem, ViewFileAPIActions, ViewFileStoreSelector);\r\n const scrollPositionHandler = useSessionStoreProperty(\r\n (state) => state.viewFiles.scroll,\r\n );\r\n\r\n if (!sessionItem.content_ready) {\r\n if (sessionItem.download_state!.id === 'download_failed') {\r\n return (\r\n <div className=\"file session\">\r\n <Message\r\n icon={IconConstants.ERROR}\r\n title={sessionT.translate('Download failed')}\r\n description={sessionItem.download_state!.str}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n return <Loader text={sessionItem.download_state!.str} />;\r\n }\r\n\r\n return (\r\n <div\r\n className={cx('file session', sessionItem.type.str, sessionItem.type.content_type)}\r\n >\r\n <FileContent\r\n file={sessionItem}\r\n sessionT={sessionT}\r\n scrollPositionHandler={scrollPositionHandler}\r\n />\r\n <FileFooter item={sessionItem} sessionT={sessionT} />\r\n </div>\r\n );\r\n};\r\n\r\nexport default FileSession;\r\n","import ViewFileConstants from '@/constants/ViewFileConstants';\r\n\r\nimport { BuildRemoveSessionAction } from '../decorators/SessionActionDecorator';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\n\r\nconst ViewFileRemoveAction = BuildRemoveSessionAction(\r\n ViewFileConstants.SESSIONS_URL,\r\n API.AccessEnum.VIEW_FILE_EDIT,\r\n);\r\n\r\nconst ViewFileActions: UI.ActionListType<API.ViewFile> = {\r\n remove: ViewFileRemoveAction,\r\n};\r\n\r\nconst ViewFileActionModule = {\r\n moduleId: UI.Modules.VIEWED_FILES,\r\n};\r\n\r\nexport const ViewFileActionMenu = {\r\n moduleData: ViewFileActionModule,\r\n actions: ViewFileActions,\r\n};\r\n","\n import API from \"!../../../../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\";\n import domAPI from \"!../../../../../node_modules/style-loader/dist/runtime/styleDomAPI.js\";\n import insertFn from \"!../../../../../node_modules/style-loader/dist/runtime/insertBySelector.js\";\n import setAttributes from \"!../../../../../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\";\n import insertStyleElement from \"!../../../../../node_modules/style-loader/dist/runtime/insertStyleElement.js\";\n import styleTagTransformFn from \"!../../../../../node_modules/style-loader/dist/runtime/styleTagTransform.js\";\n import content, * as namedExport from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n \n \n\nvar options = {};\n\noptions.styleTagTransform = styleTagTransformFn;\noptions.setAttributes = setAttributes;\noptions.insert = insertFn.bind(null, \"head\");\noptions.domAPI = domAPI;\noptions.insertStyleElement = insertStyleElement;\n\nvar update = API(content, options);\n\n\n\nexport * from \"!!../../../../../node_modules/css-loader/dist/cjs.js!./style.css\";\n export default content && content.locals ? content.locals : undefined;\n","import * as React from 'react';\r\n\r\nimport SessionLayout from '@/routes/Sidebar/components/SessionLayout';\r\n\r\nimport FileIcon from '@/components/icon/FileIcon';\r\nimport Message from '@/components/semantic/Message';\r\n\r\nimport FileSession from './FileSession';\r\n\r\nimport * as API from '@/types/api';\r\nimport * as UI from '@/types/ui';\r\nimport {\r\n SessionProviderDecoratorChildProps,\r\n SessionProviderDecorator,\r\n} from '@/routes/Sidebar/decorators/SessionProviderDecorator';\r\nimport { ViewFileActionMenu } from '@/actions/ui/viewed-file';\r\n\r\nimport { ViewFileAPIActions } from '@/actions/store/ViewFileActions';\r\nimport { ViewFileStoreSelector } from '@/stores/session/viewFileSlice';\r\n\r\nimport '../style.css';\r\nimport MenuConstants from '@/constants/MenuConstants';\r\n\r\nconst ItemHandler: UI.SessionInfoGetter<API.ViewFile> = {\r\n itemNameGetter(session) {\r\n return session.name;\r\n },\r\n\r\n itemLabelGetter() {\r\n return null;\r\n },\r\n\r\n itemHeaderDescriptionGetter() {\r\n return null;\r\n },\r\n\r\n itemHeaderIconGetter(session) {\r\n return <FileIcon typeInfo={session.type} />;\r\n },\r\n};\r\n\r\nconst Files: React.FC<SessionProviderDecoratorChildProps<API.ViewFile>> = (props) => {\r\n const { params, sessionT, ...other } = props;\r\n if (props.items.length === 0) {\r\n return (\r\n <Message\r\n title={sessionT.t('noFiles', 'No files to view')}\r\n description={sessionT.t(\r\n 'noFilesDesc',\r\n 'You may open text or media files to be viewed here from search or filelists',\r\n )}\r\n />\r\n );\r\n }\r\n\r\n return (\r\n <SessionLayout\r\n activeId={params.id}\r\n baseUrl=\"files\"\r\n disableSideMenu={true}\r\n editAccess={API.AccessEnum.VIEW_FILE_EDIT}\r\n uiActions={ViewFileActionMenu}\r\n sessionApi={ViewFileAPIActions}\r\n sessionStoreSelector={ViewFileStoreSelector}\r\n sessionItemLayout={FileSession}\r\n sessionT={sessionT}\r\n remoteMenuId={MenuConstants.VIEW_FILE}\r\n {...ItemHandler}\r\n {...other}\r\n />\r\n );\r\n};\r\n\r\nexport default SessionProviderDecorator(\r\n Files,\r\n ViewFileStoreSelector,\r\n UI.Modules.VIEWED_FILES,\r\n);\r\n","import * as React from 'react';\n\nconst formatMediaError = (event: React.SyntheticEvent<HTMLMediaElement>) => {\n const error: MediaError = (event.target as any).error;\n switch (error.code) {\n case error.MEDIA_ERR_NETWORK:\n return 'A network error caused the media download to fail';\n case error.MEDIA_ERR_DECODE:\n // eslint-disable-next-line max-len\n return 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support';\n case error.MEDIA_ERR_SRC_NOT_SUPPORTED:\n // eslint-disable-next-line max-len\n return 'The media could not be loaded, either because the file was not found, network failed or because the format is not supported by your browser';\n default:\n return 'An unknown media error occurred';\n }\n};\n\nexport interface MediaFileDecoratorChildProps\n extends Pick<MediaFileDecoratorProps, 'url'> {\n mediaRef: React.Ref<HTMLMediaElement>;\n mediaProps: {\n onError: (event: React.SyntheticEvent<HTMLMediaElement>) => void;\n autoPlay: boolean;\n controls: boolean;\n src: string;\n };\n}\n\nexport interface MediaFileDecoratorProps {\n url: string;\n autoPlay: boolean;\n}\n\nexport default function (Component: React.ComponentType<MediaFileDecoratorChildProps>) {\n const MediaFileDecorator = ({ url, autoPlay }: MediaFileDecoratorProps) => {\n const [error, setError] = React.useState<null | string>(null);\n\n const mediaRef = React.useRef<HTMLMediaElement>(null);\n\n React.useEffect(() => {\n if (mediaRef.current) {\n mediaRef.current.load();\n }\n\n // Reset the error when switching between items\n setError(null);\n }, [url]);\n\n const onMediaError = (event: React.SyntheticEvent<HTMLMediaElement>) => {\n setError(formatMediaError(event));\n };\n\n if (error) {\n return <div>{error}</div>;\n }\n\n const mediaProps = {\n onError: onMediaError,\n autoPlay,\n controls: true,\n src: url,\n };\n\n return <Component mediaRef={mediaRef} mediaProps={mediaProps} url={url} />;\n };\n\n return MediaFileDecorator;\n}\n","import * as React from 'react';\n\nimport MediaFileDecorator, {\n MediaFileDecoratorChildProps,\n} from './decorators/MediaFileDecorator';\n\nconst AudioFile: React.FC<MediaFileDecoratorChildProps> = ({ mediaRef, mediaProps }) => (\n <audio\n ref={mediaRef}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n {...mediaProps}\n >\n <track kind=\"captions\" />\n </audio>\n);\n\nconst AudioFileDecorated = MediaFileDecorator(AudioFile);\n\nexport { AudioFileDecorated as AudioFile };\n","import * as React from 'react';\n\ninterface ImageFileProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n url: string;\n}\n\nconst ImageFile: React.FC<ImageFileProps> = ({ url }) => (\n <img\n src={url}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n />\n);\n\nexport { ImageFile };\n","import { useEffect, useState } from 'react';\nimport * as React from 'react';\n\nimport { TextDecorator } from '@/components/text';\nimport Message from '@/components/semantic/Message';\n\nimport * as UI from '@/types/ui';\nimport { translate } from '@/utils/TranslationUtils';\nimport { useTranslation } from 'react-i18next';\nimport Loader from '@/components/semantic/Loader';\n\ninterface TextFileProps {\n textGetter: () => Promise<string>;\n url?: string;\n}\n\nconst TextFile: React.FC<TextFileProps> = ({ textGetter, url }) => {\n const [text, setText] = useState<string | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n const { t } = useTranslation();\n useEffect(() => {\n textGetter().then(setText).catch(setError);\n\n return () => {\n setText(null);\n setError(null);\n };\n }, [url]);\n\n if (!text) {\n if (error) {\n return (\n <Message\n title={translate('Failed to fetch content', t, UI.Modules.COMMON)}\n description={error.message}\n />\n );\n }\n\n return <Loader />;\n }\n\n return (\n <pre>\n <TextDecorator text={text} />\n </pre>\n );\n};\n\nexport { TextFile };\n","import * as React from 'react';\n\nimport MediaFileDecorator, {\n MediaFileDecoratorChildProps,\n} from './decorators/MediaFileDecorator';\n\nconst VideoFile: React.FC<MediaFileDecoratorChildProps> = ({ mediaRef, mediaProps }) => (\n <video\n ref={mediaRef as React.Ref<HTMLVideoElement>}\n style={{\n maxWidth: '100%',\n maxHeight: '100%',\n }}\n {...mediaProps}\n >\n <track kind=\"captions\" />\n </video>\n);\n\nconst VideoFileDecorated = MediaFileDecorator(VideoFile);\n\nexport { VideoFileDecorated as VideoFile };\n","import * as React from 'react';\r\n\r\nexport default function <PropsT>(\r\n Component: React.ComponentType<PropsT>,\r\n redrawIntervalSeconds = 60,\r\n) {\r\n class RedrawDecorator extends React.Component<PropsT> {\r\n redrawTimeout: number | undefined;\r\n\r\n componentDidMount() {\r\n this.scheduleComponentRefresh();\r\n }\r\n\r\n componentWillUnmount() {\r\n clearTimeout(this.redrawTimeout);\r\n }\r\n\r\n scheduleComponentRefresh = () => {\r\n this.redrawTimeout = window.setTimeout(() => {\r\n this.forceUpdate();\r\n this.scheduleComponentRefresh();\r\n }, redrawIntervalSeconds * 1000);\r\n };\r\n\r\n render() {\r\n return <Component {...this.props} />;\r\n }\r\n }\r\n\r\n return RedrawDecorator;\r\n}\r\n","// Imports\nimport ___CSS_LOADER_API_SOURCEMAP_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/sourceMaps.js\";\nimport ___CSS_LOADER_API_IMPORT___ from \"../../../../../node_modules/css-loader/dist/runtime/api.js\";\nvar ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(___CSS_LOADER_API_SOURCEMAP_IMPORT___);\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `.file.session {\n flex: 1 1 auto;\n display: flex;\n flex-direction: column;\n max-height: 100%;\n max-width: 100%;\n margin-top: 10px;\n}\n\n.file.session .content {\n flex: 1;\n overflow: auto;\n}\n\n.file.session .content pre {\n overflow: initial;\n}\n\n.file.session.nfo .file-content pre {\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\n font-size: 11px;\n line-height: 12px;\n padding: 3px;\n margin: 0px;\n}\n\n.file.session img,\n.file.session video {\n max-width: 100%;\n max-height: 99%;\n}\n\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\n:-webkit-full-screen-ancestor:not(iframe) {\n max-width: inherit !important;\n overflow-x: initial;\n}\n\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\n visibility: hidden;\n}\n`, \"\",{\"version\":3,\"sources\":[\"webpack://./src/routes/Sidebar/routes/Files/style.css\"],\"names\":[],\"mappings\":\"AAAA;EACE,cAAc;EACd,aAAa;EACb,sBAAsB;EACtB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;AAClB;;AAEA;EACE,OAAO;EACP,cAAc;AAChB;;AAEA;EACE,iBAAiB;AACnB;;AAEA;EACE,yDAAyD;EACzD,eAAe;EACf,iBAAiB;EACjB,YAAY;EACZ,WAAW;AACb;;AAEA;;EAEE,eAAe;EACf,eAAe;AACjB;;AAEA,8EAA8E;AAC9E;EACE,6BAA6B;EAC7B,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;AACpB\",\"sourcesContent\":[\".file.session {\\n flex: 1 1 auto;\\n display: flex;\\n flex-direction: column;\\n max-height: 100%;\\n max-width: 100%;\\n margin-top: 10px;\\n}\\n\\n.file.session .content {\\n flex: 1;\\n overflow: auto;\\n}\\n\\n.file.session .content pre {\\n overflow: initial;\\n}\\n\\n.file.session.nfo .file-content pre {\\n font-family: 'Courier New', 'DejaVu Sans Mono', monospace;\\n font-size: 11px;\\n line-height: 12px;\\n padding: 3px;\\n margin: 0px;\\n}\\n\\n.file.session img,\\n.file.session video {\\n max-width: 100%;\\n max-height: 99%;\\n}\\n\\n/* The fullscreen mode conflicts with layout styles in Webkit-based browsers */\\n:-webkit-full-screen-ancestor:not(iframe) {\\n max-width: inherit !important;\\n overflow-x: initial;\\n}\\n\\n:-webkit-full-screen-ancestor:not(iframe) #side-menu {\\n visibility: hidden;\\n}\\n\"],\"sourceRoot\":\"\"}]);\n// Exports\nexport default ___CSS_LOADER_EXPORT___;\n","import * as React from 'react';\r\nimport classNames from 'classnames';\r\n\r\nimport { Trans } from 'react-i18next';\r\nimport { toI18nKey } from '@/utils/TranslationUtils';\r\n\r\nimport * as UI from '@/types/ui';\r\n\r\nexport interface RowProps {\r\n title: React.ReactNode;\r\n text?: React.ReactNode;\r\n titleWidth?: string;\r\n className?: string;\r\n noText?: boolean;\r\n}\r\n\r\nconst formatText = (text: React.ReactNode) => {\r\n if (!!text) {\r\n return text;\r\n }\r\n\r\n return <Trans i18nKey={toI18nKey('na', UI.Modules.COMMON)}>N/A</Trans>;\r\n};\r\n\r\nexport const Row: React.FC<RowProps> = ({\r\n title,\r\n text,\r\n className,\r\n titleWidth = 'four',\r\n noText,\r\n}) => (\r\n <div className={classNames('ui row', className)}>\r\n <div className={classNames(noText ? 'sixteen' : titleWidth, 'wide column title')}>\r\n <div className=\"ui tiny header\" style={{ overflow: 'hidden' }}>\r\n {title}\r\n </div>\r\n </div>\r\n {!noText && <div className=\"column value\">{formatText(text)}</div>}\r\n </div>\r\n);\r\n\r\nexport interface HeaderProps {\r\n title: React.ReactNode;\r\n}\r\n\r\nexport const Header: React.FC<HeaderProps> = ({ title }) => (\r\n <div className=\"ui row\">\r\n <div className=\"sixteen wide column\">\r\n <div className=\"ui blue section header\">{title}</div>\r\n </div>\r\n </div>\r\n);\r\n\r\nexport interface GridProps extends React.HTMLAttributes<HTMLDivElement> {\r\n columns?: string;\r\n stackable?: boolean;\r\n}\r\n\r\nexport const Grid: React.FC<GridProps> = ({\r\n className,\r\n children,\r\n columns,\r\n stackable,\r\n ...other\r\n}) => (\r\n <div\r\n className={classNames(\r\n 'ui grid',\r\n //`${columns} column`,\r\n { [`${columns} column`]: !!columns },\r\n { stackable: stackable },\r\n className,\r\n )}\r\n {...other}\r\n >\r\n {children}\r\n </div>\r\n);\r\n"],"names":["RedrawDecorator","item","sessionT","formatRelativeTime","downloadState","download_state","SessionFooter","label","translate","text","time_finished","time_opened","useAutoPlay","diff","asMinutes","TextViewerElement","props","textGetter","url","then","data","onReady","AudioViewerElement","autoPlay","VideoViewerElement","getUrl","basePath","tth","authToken","memo","file","scrollPositionHandler","auth_token","scrollable","onScrollableContentReady","ViewerElement","type","content_type","getFileViewerElement","child","mime_type","extension","str","ref","className","sessionItem","state","viewFiles","scroll","content_ready","id","Message","icon","IconConstants","ERROR","title","description","Loader","remove","ViewFileConstants","SESSIONS_URL","VIEW_FILE_EDIT","ViewFileActionMenu","moduleData","moduleId","VIEWED_FILES","actions","options","styleTagTransform","setAttributes","insert","domAPI","insertStyleElement","locals","ItemHandler","itemNameGetter","session","name","itemLabelGetter","itemHeaderDescriptionGetter","itemHeaderIconGetter","FileIcon","typeInfo","SessionProviderDecorator","params","other","items","length","t","SessionLayout","activeId","baseUrl","disableSideMenu","editAccess","uiActions","sessionApi","sessionStoreSelector","sessionItemLayout","remoteMenuId","MenuConstants","VIEW_FILE","Component","error","setError","mediaRef","current","load","mediaProps","onError","event","target","code","MEDIA_ERR_NETWORK","MEDIA_ERR_DECODE","MEDIA_ERR_SRC_NOT_SUPPORTED","formatMediaError","controls","src","AudioFileDecorated","MediaFileDecorator","style","maxWidth","maxHeight","kind","ImageFile","TextFile","setText","useState","useEffect","catch","COMMON","message","VideoFileDecorated","redrawIntervalSeconds","scheduleComponentRefresh","this","redrawTimeout","window","setTimeout","forceUpdate","componentDidMount","componentWillUnmount","clearTimeout","render","___CSS_LOADER_EXPORT___","push","module","formatText","i18nKey","Row","titleWidth","noText","overflow","Header","Grid","children","columns","stackable"],"sourceRoot":""}
|