├── debian ├── .qtcreator ├── compat ├── README ├── changelog ├── acfun.aegis ├── copyright └── rules ├── qtc_packaging └── debian_harmattan │ ├── compat │ ├── README │ ├── changelog │ ├── copyright │ ├── rules │ └── manifest.aegis ├── AcFun ├── AcFun64.png ├── AcFun80.png ├── i18n └── AcFun_zh.qm ├── qml ├── gfx │ ├── avatar.jpg │ ├── msg_in.png │ ├── cover-day.png │ ├── msg_out.png │ ├── image_logo.png │ ├── meegoTLCorner.png │ ├── meegoTRCorner.png │ ├── image_upman_small.png │ ├── image_watches_small.png │ ├── image_comments_small.png │ ├── rank.svg │ ├── photos.svg │ ├── clock.svg │ ├── ok.svg │ ├── send.svg │ ├── edit.svg │ ├── tb_close_stop.svg │ ├── pull_down_inverse.svg │ ├── pull_down.svg │ └── error.svg ├── js │ ├── theme.css │ ├── VideoParser.js │ ├── QQParser.js │ ├── SinaParser.js │ ├── videoSourceLoader.js │ ├── database.js │ ├── IQiyiParser.js │ ├── LetvParser.js │ └── acapi.js ├── harmattan │ ├── Component │ │ ├── MyPage.qml │ │ ├── DynamicQueryDialog.qml │ │ ├── FooterItem.qml │ │ ├── SectionHeader.qml │ │ ├── ViewHeader.qml │ │ ├── CustomProgressBar.qml │ │ ├── FastScrollStyle.qml │ │ ├── SearchInput.qml │ │ ├── AbstractItem.qml │ │ ├── StatusPaneText.qml │ │ ├── CommonDelegate.qml │ │ ├── PullToActivate.qml │ │ └── FastScroll.js │ ├── ACPlayer │ │ ├── Comments.js │ │ ├── VisualStyle.qml │ │ ├── util.js │ │ ├── ACPlayer.qml │ │ ├── CommentLayer.qml │ │ └── VideoLayer.qml │ ├── ACSettings.qml │ ├── main.qml │ ├── Constant.qml │ ├── VideoDetailCom │ │ └── CommentUI.qml │ ├── LoginPage.qml │ ├── UserPageCom │ │ └── HistoryPage.qml │ ├── SignalCenter.qml │ ├── SeriesPageCom │ │ ├── SeriesDelegateL.qml │ │ ├── SeriesDelegate.qml │ │ └── WikiPage.qml │ ├── SearchPage.qml │ ├── SearchResultPage.qml │ ├── MainPageCom │ │ ├── HomeRow.qml │ │ └── HeaderView.qml │ ├── VideoPage.qml │ ├── RankingPage.qml │ ├── ClassPage.qml │ └── SeriesPage.qml └── AcFun │ ├── Component │ ├── DynamicQueryDialog.qml │ ├── MyPage.qml │ ├── FooterItem.qml │ ├── ViewHeader.qml │ ├── AbstractItem.qml │ ├── SearchInput.qml │ ├── StatusPaneText.qml │ ├── CommonDelegate.qml │ └── PullToActivate.qml │ ├── ACPlayer │ ├── Comments.js │ ├── VisualStyle.qml │ ├── util.js │ ├── ACPlayer.qml │ ├── CommentLayer.qml │ └── VideoLayer.qml │ ├── VideoDetailCom │ └── CommentUI.qml │ ├── ACSettings.qml │ ├── Constant.qml │ ├── main.qml │ ├── MainPageCom │ ├── FirstStartInfo.qml │ ├── HomeRow.qml │ └── HeaderView.qml │ ├── UserPageCom │ ├── HistoryPage.qml │ └── FavPage.qml │ ├── LoginPage.qml │ ├── SeriesPageCom │ ├── SeriesDelegateL.qml │ ├── SeriesDelegate.qml │ └── WikiPage.qml │ ├── SignalCenter.qml │ ├── SearchPage.qml │ ├── VideoPage.qml │ ├── SearchResultPage.qml │ ├── RankingPage.qml │ └── ClassPage.qml ├── splash ├── splash_640.png └── splash_n9.png ├── README.md ├── AcFun-res.qrc ├── AcFun.desktop ├── AcFun_harmattan.desktop ├── .gitignore ├── src ├── qnetworkrequesthelper.h ├── acnetworkaccessmanagerfactory.h ├── utility.h ├── acnetworkaccessmanagerfactory.cpp └── qnetworkrequesthelper.cpp ├── qmlapplicationviewer └── qmlapplicationviewer.h ├── AcFun.pro └── main.cpp /debian/.qtcreator: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /AcFun: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/AcFun -------------------------------------------------------------------------------- /AcFun64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/AcFun64.png -------------------------------------------------------------------------------- /AcFun80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/AcFun80.png -------------------------------------------------------------------------------- /i18n/AcFun_zh.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/i18n/AcFun_zh.qm -------------------------------------------------------------------------------- /qml/gfx/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/avatar.jpg -------------------------------------------------------------------------------- /qml/gfx/msg_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/msg_in.png -------------------------------------------------------------------------------- /qml/gfx/cover-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/cover-day.png -------------------------------------------------------------------------------- /qml/gfx/msg_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/msg_out.png -------------------------------------------------------------------------------- /splash/splash_640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/splash/splash_640.png -------------------------------------------------------------------------------- /splash/splash_n9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/splash/splash_n9.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | acfun 2 | ===== 3 | 4 | AcFun的Qt版客户端 5 | 6 | 支持Symbian Belle和MeeGo Harmattan机型 7 | -------------------------------------------------------------------------------- /qml/gfx/image_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/image_logo.png -------------------------------------------------------------------------------- /qml/gfx/meegoTLCorner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/meegoTLCorner.png -------------------------------------------------------------------------------- /qml/gfx/meegoTRCorner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/meegoTRCorner.png -------------------------------------------------------------------------------- /qml/js/theme.css: -------------------------------------------------------------------------------- 1 | body{background-color:#F1F1F1!important} 2 | img{max-width:100%;height:auto!important} 3 | -------------------------------------------------------------------------------- /qml/gfx/image_upman_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/image_upman_small.png -------------------------------------------------------------------------------- /qml/gfx/image_watches_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/image_watches_small.png -------------------------------------------------------------------------------- /qml/gfx/image_comments_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yeatse/acfun_qt/HEAD/qml/gfx/image_comments_small.png -------------------------------------------------------------------------------- /debian/README: -------------------------------------------------------------------------------- 1 | The Debian Package acfun 2 | ---------------------------- 3 | 4 | Comments regarding the Package 5 | 6 | -- unknown <> Fri, 25 Oct 2013 00:28:21 +0800 7 | -------------------------------------------------------------------------------- /AcFun-res.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | i18n/AcFun_zh.qm 4 | splash/splash_640.png 5 | 6 | 7 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/README: -------------------------------------------------------------------------------- 1 | The Debian Package acfun 2 | ---------------------------- 3 | 4 | Comments regarding the Package 5 | 6 | -- unknown <> Fri, 25 Oct 2013 00:28:21 +0800 7 | -------------------------------------------------------------------------------- /AcFun.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Version=1.0 4 | Type=Application 5 | Terminal=false 6 | Name=AcFun 7 | Exec=/opt/AcFun/bin/AcFun 8 | Icon=AcFun64 9 | X-Window-Icon= 10 | X-HildonDesk-ShowInToolbar=true 11 | X-Osso-Type=application/x-executable 12 | -------------------------------------------------------------------------------- /qml/harmattan/Component/MyPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Page { 5 | id: root; 6 | 7 | property string title: ""; 8 | property bool loading: false; 9 | 10 | orientationLock: PageOrientation.LockPortrait 11 | } 12 | -------------------------------------------------------------------------------- /AcFun_harmattan.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Version=1.0 4 | Type=Application 5 | Terminal=false 6 | Name=AcFun 7 | Exec=/usr/bin/invoker --splash /opt/AcFun/bin/splash_n9.png --type=d -s /opt/AcFun/bin/AcFun 8 | Icon=/usr/share/icons/hicolor/80x80/apps/AcFun80.png 9 | X-Window-Icon= 10 | X-HildonDesk-ShowInToolbar=true 11 | X-Osso-Type=application/x-executable 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | 3 | *.slo 4 | *.lo 5 | *.o 6 | *.a 7 | *.la 8 | *.lai 9 | *.so 10 | *.dll 11 | *.dylib 12 | *.moc 13 | 14 | # Qt-es 15 | 16 | *.pro.user 17 | *.pro.user.* 18 | moc_*.cpp 19 | qrc_*.cpp 20 | Makefile 21 | *-build-* 22 | .make.cache 23 | 24 | # Symbian 25 | bld.inf 26 | *.loc 27 | *.rss 28 | *_exe.mmp 29 | *.pkg 30 | *.sis 31 | 32 | # Meego Harmattan 33 | *_armel.* 34 | -------------------------------------------------------------------------------- /qml/js/VideoParser.js: -------------------------------------------------------------------------------- 1 | var VideoParser = new Function(); 2 | 3 | VideoParser.prototype.name = ""; 4 | 5 | VideoParser.prototype.start = function(vid){ 6 | console.log(vid); 7 | }; 8 | 9 | VideoParser.prototype.success = function(url){ 10 | console.log(url); 11 | }; 12 | 13 | VideoParser.prototype.error = function(message){ 14 | console.log(message); 15 | }; 16 | -------------------------------------------------------------------------------- /qml/AcFun/Component/DynamicQueryDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | QueryDialog { 5 | id: root; 6 | property bool __isClosing: false; 7 | onStatusChanged: { 8 | if (status == DialogStatus.Closing){ 9 | __isClosing = true; 10 | } else if (status == DialogStatus.Closed && __isClosing){ 11 | root.destroy(); 12 | } 13 | } 14 | Component.onCompleted: open(); 15 | } 16 | -------------------------------------------------------------------------------- /qml/AcFun/Component/MyPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Page { 5 | id: root; 6 | 7 | property string title: ""; 8 | property bool loading: false; 9 | 10 | orientationLock: PageOrientation.LockPortrait 11 | 12 | Binding { 13 | target: statusPaneText; 14 | property: "text"; 15 | value: root.title; 16 | when: root.visible && root.status == PageStatus.Active; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /qml/harmattan/Component/DynamicQueryDialog.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | QueryDialog { 5 | id: root; 6 | property bool __isClosing: false; 7 | onStatusChanged: { 8 | if (status == DialogStatus.Closing){ 9 | __isClosing = true; 10 | } else if (status == DialogStatus.Closed && __isClosing){ 11 | root.destroy(1000); 12 | } 13 | } 14 | Component.onCompleted: open(); 15 | } 16 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/Comments.js: -------------------------------------------------------------------------------- 1 | var commentPool = []; 2 | var commentIndex = 0; 3 | var commentVisual = []; 4 | 5 | function intToColor(colorInt){ 6 | var str = colorInt.toString(16); 7 | while(str.length < 6){ 8 | str = "0"+str; 9 | } 10 | return "#"+str; 11 | } 12 | 13 | function addToScreen(){ 14 | var i = 0; 15 | while(commentVisual[i]===1){ 16 | i ++; 17 | } 18 | commentVisual[i] = 1; 19 | return i; 20 | } 21 | 22 | function clearFromScreen(i){ 23 | commentVisual[i] = 0; 24 | } 25 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/Comments.js: -------------------------------------------------------------------------------- 1 | var commentPool = []; 2 | var commentIndex = 0; 3 | var commentVisual = []; 4 | 5 | function intToColor(colorInt){ 6 | var str = colorInt.toString(16); 7 | while(str.length < 6){ 8 | str = "0"+str; 9 | } 10 | return "#"+str; 11 | } 12 | 13 | function addToScreen(){ 14 | var i = 0; 15 | while(commentVisual[i]===1){ 16 | i ++; 17 | } 18 | commentVisual[i] = 1; 19 | return i; 20 | } 21 | 22 | function clearFromScreen(i){ 23 | commentVisual[i] = 0; 24 | } 25 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | acfun (2.2.0) unstable; urgency=low 2 | * 3 | 4 | -- Yeatse Fri, 08 Nov 2013 21:41:43 +0800 5 | 6 | acfun (2.1.1) unstable; urgency=low 7 | * 8 | 9 | -- Yeatse Fri, 08 Nov 2013 00:50:55 +0800 10 | 11 | acfun (2.0.1) unstable; urgency=low 12 | * 13 | 14 | -- Yeatse Thu, 07 Nov 2013 19:59:47 +0800 15 | 16 | acfun (0.0.1) unstable; urgency=low 17 | 18 | * Initial Release. 19 | 20 | -- Yeatse Fri, 25 Oct 2013 00:28:21 +0800 21 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/changelog: -------------------------------------------------------------------------------- 1 | acfun (2.2.0) unstable; urgency=low 2 | * 3 | 4 | -- Yeatse Fri, 08 Nov 2013 21:41:43 +0800 5 | 6 | acfun (2.1.1) unstable; urgency=low 7 | * 8 | 9 | -- Yeatse Fri, 08 Nov 2013 00:50:55 +0800 10 | 11 | acfun (2.0.1) unstable; urgency=low 12 | * 13 | 14 | -- Yeatse Thu, 07 Nov 2013 19:59:47 +0800 15 | 16 | acfun (0.0.1) unstable; urgency=low 17 | 18 | * Initial Release. 19 | 20 | -- Yeatse Fri, 25 Oct 2013 00:28:21 +0800 21 | -------------------------------------------------------------------------------- /qml/AcFun/Component/FooterItem.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | signal clicked; 8 | 9 | property Flickable listView: root.ListView.view; 10 | property string text: "继续加载"; 11 | 12 | implicitWidth: listView.width; 13 | implicitHeight: visible ? constant.graphicSizeLarge : 0; 14 | 15 | Button { 16 | anchors { 17 | left: parent.left; right: parent.right; 18 | margins: constant.paddingLarge*2; 19 | verticalCenter: parent.verticalCenter; 20 | } 21 | text: root.text; 22 | onClicked: root.clicked(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /qml/harmattan/Component/FooterItem.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | signal clicked; 8 | 9 | property Flickable listView: root.ListView.view; 10 | property string text: "继续加载"; 11 | 12 | implicitWidth: listView.width; 13 | implicitHeight: visible ? constant.graphicSizeLarge : 0; 14 | 15 | Button { 16 | anchors { 17 | left: parent.left; right: parent.right; 18 | margins: constant.paddingLarge*2; 19 | verticalCenter: parent.verticalCenter; 20 | } 21 | text: root.text; 22 | onClicked: root.clicked(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /qml/harmattan/ACSettings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: acsettings; 5 | 6 | property string accessToken: utility.getValue("accessToken",""); 7 | onAccessTokenChanged: utility.setValue("accessToken", accessToken); 8 | 9 | property double expiresBy: utility.getValue("expiresBy", 0); 10 | onExpiresByChanged: utility.setValue("expiresBy", expiresBy); 11 | 12 | property string userId: utility.getValue("userId",""); 13 | onUserIdChanged: utility.setValue("userId", userId); 14 | 15 | property bool usePlatformPlayer: utility.getValue("usePlatformPlayer", true); 16 | onUsePlatformPlayerChanged: utility.setValue("usePlatformPlayer", usePlatformPlayer); 17 | } 18 | -------------------------------------------------------------------------------- /qml/harmattan/Component/SectionHeader.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root; 5 | 6 | property string title; 7 | 8 | implicitWidth: parent.width; 9 | implicitHeight: text.height + constant.paddingMedium + constant.paddingLarge; 10 | 11 | Text { 12 | id: text; 13 | anchors { 14 | left: parent.left; leftMargin: constant.paddingSmall; 15 | top: parent.top; topMargin: constant.paddingLarge; 16 | } 17 | font: constant.titleFont; 18 | color: constant.colorLight; 19 | text: root.title; 20 | } 21 | 22 | Rectangle { 23 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom; } 24 | height: 1; 25 | color: constant.colorDisabled; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /qml/harmattan/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import com.nokia.extras 1.1 4 | import com.yeatse.acfun 1.0 5 | import "Component" 6 | import "ACPlayer" as AC 7 | import "../js/main.js" as Script 8 | 9 | PageStackWindow { 10 | id: app; 11 | 12 | initialPage: MainPage { id: mainPage; } 13 | 14 | CustomProgressBar { id: proBar; parent: pageStack; z: 10; } 15 | 16 | InfoBanner { id: infoBanner; topMargin: 36; } 17 | 18 | ACSettings { id: acsettings; } 19 | 20 | Constant { id: constant; } 21 | 22 | SignalCenter { id: signalCenter; } 23 | 24 | NetworkHelper { id: networkHelper; } 25 | 26 | AC.VisualStyle { id: visual; inPortrait: app.inPortrait; } 27 | 28 | Component.onCompleted: Script.initialize(signalCenter, acsettings, utility); 29 | } 30 | -------------------------------------------------------------------------------- /qml/harmattan/Component/ViewHeader.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Rectangle { 4 | id: root; 5 | 6 | property alias title: text.text; 7 | 8 | implicitWidth: parent.width; 9 | implicitHeight: 72; 10 | color: "#f2b200"; 11 | z: 10; 12 | 13 | Text { 14 | id: text; 15 | anchors { 16 | left: parent.left; right: parent.right; 17 | margins: constant.paddingLarge; 18 | verticalCenter: parent.verticalCenter; 19 | } 20 | font { 21 | family: constant.titleFont.family; 22 | pixelSize: constant.titleFont.pixelSize+2; 23 | } 24 | color: "#ffffff"; 25 | style: Text.Raised; 26 | styleColor: "#666666"; 27 | maximumLineCount: 2; 28 | elide: Text.ElideRight; 29 | wrapMode: Text.Wrap; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qml/AcFun/VideoDetailCom/CommentUI.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | CommonDialog { 5 | id: root; 6 | 7 | property alias text: contentArea.text; 8 | 9 | titleText: "添加评论"; 10 | 11 | buttonTexts: ["发送", "取消"]; 12 | onButtonClicked: if (index === 0) accept(); 13 | 14 | content: Item { 15 | width: parent.width; 16 | height: root.platformContentMaximumHeight; 17 | TextArea { 18 | id: contentArea; 19 | anchors { fill: parent; margins: constant.paddingLarge; } 20 | focus: true; 21 | textFormat: TextEdit.PlainText; 22 | } 23 | } 24 | 25 | onStatusChanged: { 26 | if (status === DialogStatus.Open){ 27 | contentArea.forceActiveFocus(); 28 | contentArea.openSoftwareInputPanel(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qml/AcFun/ACSettings.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: acsettings; 5 | 6 | property string accessToken: utility.getValue("accessToken",""); 7 | onAccessTokenChanged: utility.setValue("accessToken", accessToken); 8 | 9 | property double expiresBy: utility.getValue("expiresBy", 0); 10 | onExpiresByChanged: utility.setValue("expiresBy", expiresBy); 11 | 12 | property string userId: utility.getValue("userId",""); 13 | onUserIdChanged: utility.setValue("userId", userId); 14 | 15 | property bool usePlatformPlayer: utility.qtVersion < 0x040800 || 16 | utility.getValue("usePlatformPlayer", true); 17 | onUsePlatformPlayerChanged: utility.setValue("usePlatformPlayer", usePlatformPlayer); 18 | 19 | property bool showFirstHelp: utility.getValue("showFirstHelp", true); 20 | onShowFirstHelpChanged: utility.setValue("showFirstHelp", showFirstHelp); 21 | } 22 | -------------------------------------------------------------------------------- /src/qnetworkrequesthelper.h: -------------------------------------------------------------------------------- 1 | #ifndef QNETWORKREQUESTHELPER_H 2 | #define QNETWORKREQUESTHELPER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class QNetworkRequestHelper : public QObject, public QDeclarativeParserStatus 9 | { 10 | Q_OBJECT 11 | Q_INTERFACES(QDeclarativeParserStatus) 12 | 13 | public: 14 | explicit QNetworkRequestHelper(QObject *parent = 0); 15 | Q_INVOKABLE void createDeleteRequest(QUrl url); 16 | Q_INVOKABLE void createDeflatedRequest(QUrl url); 17 | 18 | signals: 19 | void requestFailed(QUrl url); 20 | void requestFinished(QUrl url, QString message); 21 | 22 | private slots: 23 | void slotRequestFinished(QNetworkReply* reply); 24 | 25 | private: 26 | virtual void classBegin(); 27 | virtual void componentComplete(); 28 | QByteArray gUncompress(const QByteArray &data); 29 | 30 | QNetworkAccessManager* nam; 31 | }; 32 | 33 | #endif // QNETWORKREQUESTHELPER_H 34 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/VisualStyle.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: visual; 5 | 6 | property bool inPortrait: false; 7 | 8 | property double currentVolume: 0; 9 | 10 | // Comment 11 | property int maxCommentCount: 20; 12 | 13 | property int controlMargins: 10; 14 | property int controlAreaHeight: 65; 15 | property int controlHeight: 50; 16 | property double controlOpacity: 0.8; 17 | property int separatorWidth: 1 18 | property color separatorColor: "#303030" 19 | property int videoControlsHideTimeout: 5000; 20 | 21 | // Busy indicator 22 | property int busyIndicatorHeight: inPortrait ? screen.displayWidth / 5 23 | : screen.displayHeight / 5 24 | property int busyIndicatorWidth: busyIndicatorHeight 25 | 26 | // Transition animation durations (in milliseconds) 27 | property int animationDurationShort: 150 28 | property int animationDurationNormal: 350 29 | property int animationDurationPrettyLong: 500 30 | property int animationDurationLong: 600 31 | } 32 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/VisualStyle.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: visual; 5 | 6 | property bool inPortrait: false; 7 | 8 | property double currentVolume: 0; 9 | 10 | // Comment 11 | property int maxCommentCount: 26; 12 | 13 | property int controlMargins: 10; 14 | property int controlAreaHeight: 65; 15 | property int controlHeight: 50; 16 | property double controlOpacity: 0.8; 17 | property int separatorWidth: 1 18 | property color separatorColor: "#303030" 19 | property int videoControlsHideTimeout: 5000; 20 | 21 | // Busy indicator 22 | property int busyIndicatorHeight: inPortrait ? screen.displayWidth / 5 23 | : screen.displayHeight / 5 24 | property int busyIndicatorWidth: busyIndicatorHeight 25 | 26 | // Transition animation durations (in milliseconds) 27 | property int animationDurationShort: 150 28 | property int animationDurationNormal: 350 29 | property int animationDurationPrettyLong: 500 30 | property int animationDurationLong: 600 31 | } 32 | -------------------------------------------------------------------------------- /qml/harmattan/Constant.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: constant; 5 | 6 | // public 7 | property color colorLight: "#191919"; 8 | property color colorMid: "#666666"; 9 | property color colorDisabled: "#b2b2b4"; 10 | 11 | property int paddingSmall: 4; 12 | property int paddingMedium: 8; 13 | property int paddingLarge: 12; 14 | 15 | property int graphicSizeTiny: 24; 16 | property int graphicSizeSmall: 32; 17 | property int graphicSizeMedium: 48; 18 | property int graphicSizeLarge: 72; 19 | 20 | property variant labelFont: __label.font; 21 | property variant titleFont: __titleText.font; 22 | property variant subTitleFont: __subTitleText.font; 23 | 24 | // private 25 | property Text __titleText: Text { 26 | font { pixelSize: 26; family: "Nokia Pure Text"; } 27 | } 28 | property Text __subTitleText: Text { 29 | font { pixelSize: 22; family: "Nokia Pure Text"; weight: Font.Light; } 30 | } 31 | property Text __label: Text { 32 | font { pixelSize: 24; family: "Nokia Pure Text"; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /debian/acfun.aegis: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /qml/AcFun/Component/ViewHeader.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Rectangle { 4 | id: root; 5 | 6 | property alias title: text.text; 7 | 8 | implicitWidth: screen.width; 9 | implicitHeight: privateStyle.tabBarHeightPortrait; 10 | color: "#f2b200"; 11 | z: 10; 12 | Image { 13 | anchors { left: parent.left; top: parent.top; } 14 | source: "../../gfx/meegoTLCorner.png"; 15 | } 16 | Image { 17 | anchors { right: parent.right; top: parent.top; } 18 | source: "../../gfx/meegoTRCorner.png"; 19 | } 20 | 21 | Text { 22 | id: text; 23 | anchors { 24 | left: parent.left; right: parent.right; 25 | margins: constant.paddingLarge; 26 | verticalCenter: parent.verticalCenter; 27 | } 28 | font { 29 | family: constant.titleFont.family; 30 | pixelSize: constant.titleFont.pixelSize+2; 31 | } 32 | color: constant.colorLight; 33 | style: Text.Raised; 34 | styleColor: constant.colorMid; 35 | maximumLineCount: 2; 36 | elide: Text.ElideRight; 37 | wrapMode: Text.Wrap; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /qml/gfx/rank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /qml/js/QQParser.js: -------------------------------------------------------------------------------- 1 | var QQParser = new Function(); 2 | QQParser.prototype = new VideoParser(); 3 | QQParser.prototype.constructor = QQParser; 4 | QQParser.prototype.name = "QQ"; 5 | 6 | QQParser.prototype.start = function(vid){ 7 | var xhr = new XMLHttpRequest(); 8 | xhr.onreadystatechange = function(){ 9 | if (xhr.readyState === XMLHttpRequest.DONE){ 10 | if (xhr.status == 200){ 11 | var QZOutputJson; 12 | try { 13 | eval(xhr.responseText); 14 | var url = QZOutputJson.vd.vi[0].url; 15 | QQParser.prototype.success(url); 16 | return; 17 | } catch(e){ 18 | } 19 | } 20 | QQParser.prototype.error(); 21 | } 22 | } 23 | xhr.open("GET", "http://vv.video.qq.com/geturl?vid=%1&otype=json".arg(vid)); 24 | xhr.send(); 25 | } 26 | -------------------------------------------------------------------------------- /qml/AcFun/Constant.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | QtObject { 5 | id: constant; 6 | 7 | // public 8 | property color colorLight: platformStyle.colorNormalLight; 9 | property color colorMid: platformStyle.colorNormalMid; 10 | property color colorDisabled: platformStyle.colorDisabledLight; 11 | property color colorLink: platformStyle.colorNormalLink; 12 | 13 | property int paddingSmall: platformStyle.paddingSmall; 14 | property int paddingMedium: platformStyle.paddingMedium; 15 | property int paddingLarge: platformStyle.paddingLarge; 16 | 17 | property int graphicSizeTiny: platformStyle.graphicSizeTiny; 18 | property int graphicSizeSmall: platformStyle.graphicSizeSmall; 19 | property int graphicSizeMedium: platformStyle.graphicSizeMedium; 20 | property int graphicSizeLarge: platformStyle.graphicSizeLarge; 21 | 22 | property variant labelFont: __label.font; 23 | property variant titleFont: __titleText.font; 24 | property variant subTitleFont: __subTitleText.font; 25 | 26 | // private 27 | property ListItemText __titleText: ListItemText {} 28 | property ListItemText __subTitleText: ListItemText { role: "SubTitle"; } 29 | property Label __label: Label {} 30 | } 31 | -------------------------------------------------------------------------------- /qml/harmattan/Component/CustomProgressBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root 5 | 6 | property bool running: true; 7 | visible: pageStack.currentPage.loading||false; 8 | 9 | implicitWidth: app.inPortrait ? screen.displayHeight : screen.displayWidth; 10 | implicitHeight: constant.paddingMedium; 11 | 12 | Rectangle { 13 | id: progressRect 14 | color: "steelblue" 15 | width: constant.graphicSizeSmall; 16 | height: constant.paddingMedium; 17 | } 18 | 19 | SequentialAnimation { 20 | id: loadingAnimation 21 | alwaysRunToEnd: true 22 | loops: Animation.Infinite 23 | running: root.running && root.visible && Qt.application.active 24 | 25 | PropertyAction { target: progressRect; property: "visible"; value: true } 26 | PropertyAction { target: progressRect; property: "x"; value: 0 } 27 | PropertyAnimation { target: progressRect; property: "x"; to: root.width/2; duration: 800; easing.type: Easing.InOutQuad} 28 | PropertyAnimation { target: progressRect; property: "x"; to: root.width; duration: 800; easing.type: Easing.InOutQuad} 29 | PropertyAction { target: progressRect; property: "visible"; value: false } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /qml/AcFun/main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import com.nokia.extras 1.1 4 | import QtMobility.systeminfo 1.1 5 | import com.yeatse.acfun 1.0 6 | import "Component" 7 | import "ACPlayer" as AC 8 | import "../js/main.js" as Script 9 | 10 | PageStackWindow { 11 | id: app; 12 | 13 | focus: true; 14 | 15 | platformSoftwareInputPanelEnabled: utility.qtVersion > 0x040800; 16 | 17 | initialPage: MainPage { id: mainPage; } 18 | 19 | StatusPaneText { id: statusPaneText; } 20 | 21 | InfoBanner { id: infoBanner; iconSource: "../gfx/error.svg" } 22 | 23 | ACSettings { id: acsettings; } 24 | 25 | Constant { id: constant; } 26 | 27 | SignalCenter { id: signalCenter; } 28 | 29 | NetworkHelper { id: networkHelper; } 30 | 31 | AC.VisualStyle { 32 | id: visual; 33 | inPortrait: app.inPortrait; 34 | currentVolume: devInfo.voiceRingtoneVolume / 100; 35 | } 36 | 37 | DeviceInfo { 38 | id: devInfo; 39 | monitorCurrentProfileChanges: true; 40 | onCurrentProfileChanged: { 41 | visual.currentVolume = devInfo.voiceRingtoneVolume / 100; 42 | } 43 | } 44 | 45 | Component.onCompleted: Script.initialize(signalCenter, acsettings, utility); 46 | } 47 | -------------------------------------------------------------------------------- /qml/js/SinaParser.js: -------------------------------------------------------------------------------- 1 | var SinaParser = new Function(); 2 | SinaParser.prototype = new VideoParser(); 3 | SinaParser.prototype.constructor = SinaParser; 4 | SinaParser.prototype.name = "新浪"; 5 | 6 | SinaParser.prototype.start = function(vid){ 7 | var url = "http://video.sina.com.cn/interface/video_ids/video_ids.php?v="+vid; 8 | var xhr = new XMLHttpRequest(); 9 | xhr.onreadystatechange = function(){ 10 | if (xhr.readyState === XMLHttpRequest.DONE){ 11 | if (xhr.status === 200){ 12 | try { 13 | var obj = JSON.parse(xhr.responseText); 14 | if (obj.ipad_vid !== 0){ 15 | SinaParser.prototype.success("http://v.iask.com/v_play_ipad.php?vid="+obj.ipad_vid); 16 | return; 17 | } else { 18 | } 19 | } catch (e){ 20 | } 21 | } 22 | SinaParser.prototype.error(); 23 | } 24 | } 25 | xhr.open("GET", url); 26 | xhr.send(); 27 | } 28 | -------------------------------------------------------------------------------- /src/acnetworkaccessmanagerfactory.h: -------------------------------------------------------------------------------- 1 | #ifndef ACNETWORKACCESSMANAGERFACTORY_H 2 | #define ACNETWORKACCESSMANAGERFACTORY_H 3 | 4 | #include 5 | #include 6 | 7 | class ACNetworkAccessManagerFactory : public QDeclarativeNetworkAccessManagerFactory 8 | { 9 | public: 10 | explicit ACNetworkAccessManagerFactory(); 11 | virtual QNetworkAccessManager* create(QObject *parent); 12 | 13 | private: 14 | QMutex mutex; 15 | }; 16 | 17 | class ACNetworkAccessManager : public QNetworkAccessManager 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit ACNetworkAccessManager(QObject *parent = 0); 22 | 23 | protected: 24 | QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData); 25 | }; 26 | 27 | class ACNetworkCookieJar : public QNetworkCookieJar 28 | { 29 | public: 30 | static ACNetworkCookieJar* GetInstance(); 31 | void clearCookies(); 32 | 33 | virtual QList cookiesForUrl(const QUrl &url) const; 34 | virtual bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); 35 | 36 | void save(); 37 | void load(); 38 | 39 | private: 40 | explicit ACNetworkCookieJar(QObject *parent = 0); 41 | ~ACNetworkCookieJar(); 42 | 43 | mutable QMutex mutex; 44 | }; 45 | 46 | #endif // ACNETWORKACCESSMANAGERFACTORY_H 47 | -------------------------------------------------------------------------------- /qml/harmattan/VideoDetailCom/CommentUI.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Sheet { 5 | id: root; 6 | 7 | property alias text: contentArea.text; 8 | 9 | acceptButtonText: "发送"; 10 | rejectButtonText: "取消"; 11 | 12 | content: Flickable { 13 | id: contentFlickable; 14 | anchors.fill: parent; 15 | contentWidth: parent.width; 16 | contentHeight: contentArea.height + constant.paddingLarge*2; 17 | clip: true; 18 | TextArea { 19 | id: contentArea; 20 | property int minHeight: contentFlickable.height - constant.paddingLarge*2; 21 | anchors { 22 | left: parent.left; right: parent.right; 23 | top: parent.top; 24 | margins: constant.paddingLarge; 25 | } 26 | focus: true; 27 | textFormat: TextEdit.PlainText; 28 | placeholderText: "输入评论内容"; 29 | function setHeight(){ contentArea.height = Math.max(implicitHeight, minHeight) } 30 | onMinHeightChanged: setHeight(); 31 | onImplicitHeightChanged: setHeight(); 32 | } 33 | } 34 | 35 | onStatusChanged: { 36 | if (status === DialogStatus.Open){ 37 | contentArea.forceActiveFocus(); 38 | contentArea.platformOpenSoftwareInputPanel(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /qml/harmattan/Component/FastScrollStyle.qml: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2012 Dickson Leong 3 | This file is part of Tweetian. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | import QtQuick 1.1 20 | import com.nokia.meego 1.0 // for Style 21 | 22 | Style { 23 | 24 | // Font 25 | property int fontPixelSize: 68 26 | property bool fontBoldProperty: true 27 | 28 | // Color 29 | property color textColor: inverted?"#000":"#fff" 30 | 31 | property string handleImage: "image://theme/meegotouch-fast-scroll-handle"+__invertedString 32 | property string magnifierImage: "image://theme/meegotouch-fast-scroll-magnifier"+__invertedString 33 | property string railImage: "image://theme/meegotouch-fast-scroll-rail"+__invertedString 34 | } 35 | -------------------------------------------------------------------------------- /qml/harmattan/LoginPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import QtWebKit 1.0 4 | import "Component" 5 | import "../js/main.js" as Script 6 | 7 | MyPage { 8 | id: page; 9 | 10 | tools: ToolBarLayout { 11 | ToolIcon { 12 | platformIconId: "toolbar-back"; 13 | onClicked: pageStack.pop(); 14 | } 15 | } 16 | 17 | onStatusChanged: { 18 | if (status == PageStatus.Active){ 19 | webView.url = Script.getAuthUrl(); 20 | } 21 | } 22 | 23 | ViewHeader { 24 | id: viewHeader; 25 | title: "登录"; 26 | } 27 | 28 | Flickable { 29 | id: view; 30 | anchors { fill: parent; topMargin: viewHeader.height; } 31 | contentWidth: webView.width; 32 | contentHeight: webView.height; 33 | WebView { 34 | id: webView; 35 | preferredWidth: view.width; 36 | preferredHeight: view.height; 37 | onUrlChanged: { 38 | var result = Script.authUrlChanged(url); 39 | if (result){ 40 | signalCenter.showMessage("登录成功!"); 41 | pageStack.pop(); 42 | } 43 | } 44 | onLoadStarted: page.loading = true; 45 | onLoadFinished: page.loading = false; 46 | onLoadFailed: page.loading = false; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /qml/js/videoSourceLoader.js: -------------------------------------------------------------------------------- 1 | Qt.include("VideoParser.js"); 2 | Qt.include("SinaParser.js"); 3 | Qt.include("YoukuParser.js"); 4 | Qt.include("QQParser.js"); 5 | Qt.include("LetvParser.js"); 6 | Qt.include("IQiyiParser.js"); 7 | 8 | var sid, type, model; 9 | 10 | function loadSource(t, s, m){ 11 | sid = s; type = t; model = m; 12 | 13 | var parser; 14 | if (type === "sina") 15 | parser = new SinaParser(); 16 | else if (type === "youku") 17 | parser = new YoukuParser(); 18 | else if (type === "qq") 19 | parser = new QQParser(); 20 | else if (type === "letv") 21 | parser = new LetvParser(); 22 | else if (type === "iqiyi") 23 | parser = new IQiyiParser(); 24 | 25 | if (parser == undefined){ 26 | addMessage("未支持的视频源:"+type); 27 | } else { 28 | addMessage("视频源来自%1,正在解析视频...".arg(parser.name)); 29 | parser.start(sid); 30 | } 31 | } 32 | 33 | function addMessage(msg){ 34 | model.append({"text": msg}); 35 | } 36 | 37 | VideoParser.prototype.success = function(url){ 38 | if (acsettings.usePlatformPlayer){ 39 | addMessage("正在打开本地播放器..."); 40 | utility.launchPlayer(url); 41 | exit(); 42 | } else { 43 | addMessage("正在打开播放器..."); 44 | createPlayer(url); 45 | } 46 | } 47 | 48 | VideoParser.prototype.error = function(message){ 49 | addMessage("视频解析失败> <"); 50 | } 51 | -------------------------------------------------------------------------------- /qmlapplicationviewer/qmlapplicationviewer.h: -------------------------------------------------------------------------------- 1 | // checksum 0x898f version 0x70013 2 | /* 3 | This file was generated by the Qt Quick Application wizard of Qt Creator. 4 | QmlApplicationViewer is a convenience class containing mobile device specific 5 | code such as screen orientation handling. Also QML paths and debugging are 6 | handled here. 7 | It is recommended not to modify this file, since newer versions of Qt Creator 8 | may offer an updated version of it. 9 | */ 10 | 11 | #ifndef QMLAPPLICATIONVIEWER_H 12 | #define QMLAPPLICATIONVIEWER_H 13 | 14 | #include 15 | 16 | class QmlApplicationViewer : public QDeclarativeView 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | enum ScreenOrientation { 22 | ScreenOrientationLockPortrait, 23 | ScreenOrientationLockLandscape, 24 | ScreenOrientationAuto 25 | }; 26 | 27 | explicit QmlApplicationViewer(QWidget *parent = 0); 28 | virtual ~QmlApplicationViewer(); 29 | 30 | static QmlApplicationViewer *create(); 31 | 32 | void setMainQmlFile(const QString &file); 33 | void addImportPath(const QString &path); 34 | 35 | // Note that this will only have an effect on Symbian and Fremantle. 36 | void setOrientation(ScreenOrientation orientation); 37 | 38 | void showExpanded(); 39 | 40 | private: 41 | class QmlApplicationViewerPrivate *d; 42 | }; 43 | 44 | QApplication *createApplication(int &argc, char **argv); 45 | 46 | #endif // QMLAPPLICATIONVIEWER_H 47 | -------------------------------------------------------------------------------- /qml/AcFun/MainPageCom/FirstStartInfo.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | CommonDialog { 5 | id: root; 6 | titleText: "提醒"; 7 | titleIcon: "../../gfx/error.svg"; 8 | content: Item { 9 | width: parent.width; 10 | height: contentCol.height + platformStyle.paddingLarge*2; 11 | Column { 12 | id: contentCol; 13 | anchors { 14 | left: parent.left; right: parent.right; 15 | top: parent.top; margins: platformStyle.paddingLarge; 16 | } 17 | spacing: platformStyle.paddingMedium; 18 | Label { 19 | id: message; 20 | width: parent.width; 21 | wrapMode: Text.Wrap; 22 | text: "为保证视频能够正常播放,使用前请先至手机系统设置→应用程序设置→视频下设置合适的接入点。" 23 | } 24 | CheckBox { 25 | id: checkBox; 26 | text: "以后不再提示"; 27 | } 28 | } 29 | } 30 | buttonTexts: ["确定"]; 31 | onButtonClicked: accept(); 32 | onAccepted: { 33 | if (checkBox.checked){ 34 | acsettings.showFirstHelp = false; 35 | } 36 | } 37 | property bool __isClosing: false; 38 | onStatusChanged: { 39 | if (status == DialogStatus.Closing){ 40 | __isClosing = true; 41 | } else if (status == DialogStatus.Closed && __isClosing){ 42 | root.destroy(); 43 | } 44 | } 45 | Component.onCompleted: open(); 46 | } 47 | -------------------------------------------------------------------------------- /qml/harmattan/Component/SearchInput.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | TextField { 5 | id: root; 6 | 7 | signal typeStopped; 8 | signal cleared; 9 | 10 | onTextChanged: { 11 | inputTimer.restart(); 12 | } 13 | 14 | platformStyle: TextFieldStyle { 15 | paddingLeft: searchIcon.width+constant.paddingMedium; 16 | paddingRight: clearButton.width; 17 | } 18 | 19 | Timer { 20 | id: inputTimer; 21 | interval: 500; 22 | onTriggered: root.typeStopped(); 23 | } 24 | 25 | Image { 26 | id: searchIcon; 27 | anchors { left: parent.left; leftMargin: constant.paddingMedium; verticalCenter: parent.verticalCenter; } 28 | height: constant.graphicSizeSmall; 29 | width: constant.graphicSizeSmall; 30 | sourceSize: Qt.size(width, height); 31 | smooth: true; 32 | source: "image://theme/icon-m-toolbar-search"; 33 | } 34 | 35 | ToolIcon { 36 | id: clearButton; 37 | anchors { right: parent.right; verticalCenter: parent.verticalCenter; } 38 | opacity: root.activeFocus ? 1 : 0; 39 | platformIconId: "toolbar-close"; 40 | Behavior on opacity { 41 | NumberAnimation { duration: 100; } 42 | } 43 | onClicked: { 44 | root.platformCloseSoftwareInputPanel(); 45 | root.text = ""; 46 | root.cleared(); 47 | root.parent.forceActiveFocus(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /qml/AcFun/UserPageCom/HistoryPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "../Component" 4 | import "../../js/database.js" as Database 5 | 6 | MyPage { 7 | id: page; 8 | 9 | tools: ToolBarLayout { 10 | ToolButton { 11 | iconSource: "toolbar-back"; 12 | onClicked: pageStack.pop(); 13 | } 14 | ToolButton { 15 | iconSource: "toolbar-refresh"; 16 | onClicked: Database.loadHistory(view.model); 17 | } 18 | ToolButton { 19 | iconSource: "toolbar-delete"; 20 | onClicked: { 21 | var s = function(){ 22 | Database.clearHistory(); 23 | view.model.clear(); 24 | } 25 | signalCenter.createQueryDialog("警告", 26 | "确定要清空历史记录?", 27 | "确定", 28 | "取消", 29 | s); 30 | } 31 | } 32 | } 33 | 34 | ViewHeader { 35 | id: viewHeader; 36 | title: page.title; 37 | } 38 | 39 | ListView { 40 | id: view; 41 | anchors { fill: parent; topMargin: viewHeader.height; } 42 | model: ListModel {} 43 | delegate: CommonDelegate {} 44 | } 45 | 46 | ScrollDecorator { flickableItem: view; } 47 | 48 | Component.onCompleted: Database.loadHistory(view.model); 49 | } 50 | -------------------------------------------------------------------------------- /qml/harmattan/UserPageCom/HistoryPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "../Component" 4 | import "../../js/database.js" as Database 5 | 6 | MyPage { 7 | id: page; 8 | 9 | tools: ToolBarLayout { 10 | ToolIcon { 11 | platformIconId: "toolbar-back"; 12 | onClicked: pageStack.pop(); 13 | } 14 | ToolIcon { 15 | platformIconId: "toolbar-refresh"; 16 | onClicked: Database.loadHistory(view.model); 17 | } 18 | ToolIcon { 19 | platformIconId: "toolbar-delete"; 20 | onClicked: { 21 | var s = function(){ 22 | Database.clearHistory(); 23 | view.model.clear(); 24 | } 25 | signalCenter.createQueryDialog("警告", 26 | "确定要清空历史记录?", 27 | "确定", 28 | "取消", 29 | s); 30 | } 31 | } 32 | } 33 | 34 | ViewHeader { 35 | id: viewHeader; 36 | title: page.title; 37 | } 38 | 39 | ListView { 40 | id: view; 41 | anchors { fill: parent; topMargin: viewHeader.height; } 42 | model: ListModel {} 43 | delegate: CommonDelegate {} 44 | } 45 | 46 | ScrollDecorator { flickableItem: view; } 47 | 48 | Component.onCompleted: Database.loadHistory(view.model); 49 | } 50 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by unknown <> on 2 | Fri, 25 Oct 2013 00:28:21 +0800. 3 | 4 | It was downloaded from 5 | 6 | Upstream Author(s): 7 | 8 | 9 | 10 | 11 | Copyright: 12 | 13 | 14 | 15 | 16 | License: 17 | 18 | This package is free software; you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation; either version 2 of the License, or 21 | (at your option) any later version. 22 | 23 | This package is distributed in the hope that it will be useful, 24 | but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | GNU General Public License for more details. 27 | 28 | You should have received a copy of the GNU General Public License 29 | along with this package; if not, write to the Free Software 30 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 31 | 32 | On Debian systems, the complete text of the GNU General 33 | Public License can be found in `/usr/share/common-licenses/GPL'. 34 | 35 | The Debian packaging is (C) 2013, unknown <> and 36 | is licensed under the GPL, see above. 37 | 38 | 39 | # Please also look if there are files or directories which have a 40 | # different copyright/license attached and list them here. 41 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by unknown <> on 2 | Fri, 25 Oct 2013 00:28:21 +0800. 3 | 4 | It was downloaded from 5 | 6 | Upstream Author(s): 7 | 8 | 9 | 10 | 11 | Copyright: 12 | 13 | 14 | 15 | 16 | License: 17 | 18 | This package is free software; you can redistribute it and/or modify 19 | it under the terms of the GNU General Public License as published by 20 | the Free Software Foundation; either version 2 of the License, or 21 | (at your option) any later version. 22 | 23 | This package is distributed in the hope that it will be useful, 24 | but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | GNU General Public License for more details. 27 | 28 | You should have received a copy of the GNU General Public License 29 | along with this package; if not, write to the Free Software 30 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 31 | 32 | On Debian systems, the complete text of the GNU General 33 | Public License can be found in `/usr/share/common-licenses/GPL'. 34 | 35 | The Debian packaging is (C) 2013, unknown <> and 36 | is licensed under the GPL, see above. 37 | 38 | 39 | # Please also look if there are files or directories which have a 40 | # different copyright/license attached and list them here. 41 | -------------------------------------------------------------------------------- /qml/gfx/photos.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /qml/AcFun/LoginPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import QtWebKit 1.0 4 | import "Component" 5 | import "../js/main.js" as Script 6 | 7 | MyPage { 8 | id: page; 9 | 10 | title: viewHeader.title; 11 | 12 | tools: ToolBarLayout { 13 | ToolButton { 14 | iconSource: "toolbar-back"; 15 | onClicked: pageStack.pop(); 16 | } 17 | } 18 | 19 | onStatusChanged: { 20 | if (status == PageStatus.Active){ 21 | webView.url = Script.getAuthUrl(); 22 | } 23 | } 24 | 25 | ViewHeader { 26 | id: viewHeader; 27 | title: webView.title||"登录"; 28 | } 29 | 30 | Flickable { 31 | id: view; 32 | anchors { fill: parent; topMargin: viewHeader.height; } 33 | contentWidth: webView.width; 34 | contentHeight: webView.height; 35 | WebView { 36 | id: webView; 37 | preferredWidth: view.width; 38 | preferredHeight: view.height; 39 | settings { 40 | minimumFontSize: platformStyle.fontSizeMedium; 41 | minimumLogicalFontSize: platformStyle.fontSizeMedium; 42 | defaultFontSize: platformStyle.fontSizeMedium; 43 | defaultFixedFontSize: platformStyle.fontSizeMedium; 44 | } 45 | onUrlChanged: { 46 | var result = Script.authUrlChanged(url); 47 | if (result){ 48 | signalCenter.showMessage("登录成功!"); 49 | pageStack.pop(); 50 | } 51 | } 52 | onLoadStarted: page.loading = true; 53 | onLoadFinished: page.loading = false; 54 | onLoadFailed: page.loading = false; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /qml/harmattan/SignalCenter.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: signalCenter; 5 | 6 | signal userChanged; 7 | signal initialized; 8 | 9 | property variant videocategories: []; 10 | property variant queryDialogComp: null; 11 | 12 | function showMessage(msg){ 13 | if (msg||false){ 14 | infoBanner.text = msg; 15 | infoBanner.show(); 16 | } 17 | } 18 | 19 | function viewDetail(vid){ 20 | var id; 21 | if (typeof(vid) === "number"){ 22 | id = vid; 23 | } else if (typeof(vid) === "string"){ 24 | var tmp = vid.match(/(videoinfo\?id=ac|\b)(\d+)\b/); 25 | if (tmp) id = tmp[2]; 26 | else return; 27 | } 28 | pageStack.push(Qt.resolvedUrl("VideoDetailPage.qml"), {"acId": id}); 29 | } 30 | 31 | function playVideo(acId, type, sid, cid){ 32 | console.log("play video==============\n", acId, type, sid, cid); 33 | var prop = { acId: acId, type: type, sid: sid, cid: cid }; 34 | var p = pageStack.push(Qt.resolvedUrl("VideoPage.qml"), prop, true); 35 | p.load(); 36 | } 37 | 38 | function login(){ 39 | pageStack.push(Qt.resolvedUrl("LoginPage.qml")); 40 | } 41 | 42 | function createQueryDialog(title, message, acceptText, rejectText, acceptCallback, rejectCallback){ 43 | if (!queryDialogComp){ queryDialogComp = Qt.createComponent("Component/DynamicQueryDialog.qml"); } 44 | var prop = { titleText: title, message: message.concat("\n"), acceptButtonText: acceptText, rejectButtonText: rejectText }; 45 | var diag = queryDialogComp.createObject(pageStack.currentPage, prop); 46 | if (acceptCallback) diag.accepted.connect(acceptCallback); 47 | if (rejectCallback) diag.rejected.connect(rejectCallback); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /qml/AcFun/SeriesPageCom/SeriesDelegateL.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import "../Component" 3 | 4 | AbstractItem { 5 | id: root; 6 | 7 | implicitHeight: 90 + constant.paddingLarge*2; 8 | onClicked: pageStack.push(Qt.resolvedUrl("SeriesDetailPage.qml"), 9 | {acId: model.id}); 10 | 11 | Image { 12 | id: preview; 13 | anchors { 14 | left: root.paddingItem.left; 15 | top: root.paddingItem.top; 16 | bottom: root.paddingItem.bottom; 17 | } 18 | clip: true; 19 | width: 120; 20 | sourceSize.width: 120; 21 | fillMode: Image.PreserveAspectCrop; 22 | source: model.cover; 23 | } 24 | Column { 25 | anchors { 26 | left: preview.right; leftMargin: constant.paddingMedium; 27 | right: root.paddingItem.right; top: root.paddingItem.top; 28 | } 29 | Text { 30 | width: parent.width; 31 | elide: Text.ElideRight; 32 | wrapMode: Text.Wrap; 33 | maximumLineCount: 2; 34 | textFormat: Text.PlainText; 35 | font: constant.titleFont; 36 | color: constant.colorLight; 37 | text: model.title; 38 | } 39 | Text { 40 | width: parent.width; 41 | elide: Text.ElideRight; 42 | wrapMode: Text.Wrap; 43 | maximumLineCount: 1; 44 | textFormat: Text.PlainText; 45 | font: constant.subTitleFont; 46 | color: constant.colorMid; 47 | text: model.intro; 48 | } 49 | Text { 50 | width: parent.width; 51 | elide: Text.ElideRight; 52 | textFormat: Text.PlainText; 53 | font: constant.subTitleFont; 54 | color: constant.colorMid; 55 | text: model.subhead 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /qml/harmattan/SeriesPageCom/SeriesDelegateL.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import "../Component" 3 | 4 | AbstractItem { 5 | id: root; 6 | 7 | implicitHeight: 120 + constant.paddingLarge*2; 8 | onClicked: pageStack.push(Qt.resolvedUrl("SeriesDetailPage.qml"), 9 | {acId: model.id}); 10 | 11 | Image { 12 | id: preview; 13 | anchors { 14 | left: root.paddingItem.left; 15 | top: root.paddingItem.top; 16 | bottom: root.paddingItem.bottom; 17 | } 18 | clip: true; 19 | width: 160; 20 | sourceSize.width: 160; 21 | fillMode: Image.PreserveAspectCrop; 22 | source: model.cover; 23 | } 24 | Column { 25 | anchors { 26 | left: preview.right; leftMargin: constant.paddingMedium; 27 | right: root.paddingItem.right; top: root.paddingItem.top; 28 | } 29 | Text { 30 | width: parent.width; 31 | elide: Text.ElideRight; 32 | wrapMode: Text.Wrap; 33 | maximumLineCount: 1; 34 | textFormat: Text.PlainText; 35 | font: constant.titleFont; 36 | color: constant.colorLight; 37 | text: model.title; 38 | } 39 | Text { 40 | width: parent.width; 41 | elide: Text.ElideRight; 42 | wrapMode: Text.Wrap; 43 | maximumLineCount: 1; 44 | textFormat: Text.PlainText; 45 | font: constant.subTitleFont; 46 | color: constant.colorMid; 47 | text: model.intro; 48 | } 49 | Text { 50 | width: parent.width; 51 | elide: Text.ElideRight; 52 | textFormat: Text.PlainText; 53 | font: constant.subTitleFont; 54 | color: constant.colorMid; 55 | text: model.subhead 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /qml/js/database.js: -------------------------------------------------------------------------------- 1 | .pragma library 2 | 3 | var QUERY = { 4 | DBVER: "2.1", 5 | CREATE_HISTORY_TABLE: 'CREATE TABLE IF NOT EXISTS History(acId INTEGER UNIQUE, channelId INTEGER, '+ 6 | 'name TEXT, previewurl TEXT, viewernum INTEGER, creatorName TEXT)' 7 | } 8 | 9 | var db = openDatabaseSync("AcFun", "", "AcFun Database", 1000000); 10 | 11 | if (db.version !== QUERY.DBVER){ 12 | var change = function (tx){ 13 | tx.executeSql('DROP TABLE IF EXISTS History'); 14 | tx.executeSql(QUERY.CREATE_HISTORY_TABLE); 15 | } 16 | db.changeVersion(db.version, QUERY.DBVER, change); 17 | } else { 18 | var trans = function(tx){ 19 | tx.executeSql(QUERY.CREATE_HISTORY_TABLE); 20 | } 21 | db.transaction(trans); 22 | } 23 | 24 | function storeHistory(acId, channelId, name, previewurl, viewernum, creatorName){ 25 | db.transaction(function(tx){ 26 | tx.executeSql('INSERT OR REPLACE INTO History VALUES (?,?,?,?,?,?)', 27 | [acId, channelId, name, previewurl, viewernum, creatorName]); 28 | }) 29 | } 30 | 31 | function loadHistory(model){ 32 | model.clear(); 33 | db.readTransaction(function(tx){ 34 | var rs = tx.executeSql('SELECT * FROM History'); 35 | for (var i=rs.rows.length-1; i>=0; i--){ 36 | var prop = rs.rows.item(i); 37 | prop.acId = Number(prop.acId); 38 | prop.viewernum = Number(prop.viewernum); 39 | prop.channelId = Number(prop.channelId); 40 | model.append(prop); 41 | } 42 | }) 43 | } 44 | 45 | function clearHistory(){ 46 | db.transaction(function(tx){ 47 | tx.executeSql('DELETE FROM History'); 48 | }) 49 | } 50 | -------------------------------------------------------------------------------- /qml/harmattan/Component/AbstractItem.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | property alias paddingItem: paddingItem; 8 | 9 | signal clicked; 10 | signal pressAndHold; 11 | 12 | implicitWidth: ListView.view ? ListView.view.width : parent.width; 13 | implicitHeight: constant.graphicSizeLarge; 14 | 15 | Item { 16 | id: paddingItem; 17 | anchors { 18 | left: parent.left; leftMargin: constant.paddingLarge; 19 | right: parent.right; rightMargin: constant.paddingLarge; 20 | top: parent.top; topMargin: constant.paddingLarge; 21 | bottom: parent.bottom; bottomMargin: constant.paddingLarge; 22 | } 23 | } 24 | 25 | Loader { 26 | id: highlightLoader; 27 | anchors.fill: parent; 28 | Component { 29 | id: highlightComp; 30 | Image { 31 | visible: mouseArea.pressed; 32 | source: theme.inverted ? "image://theme/meegotouch-panel-inverted-background-pressed" 33 | : "image://theme/meegotouch-panel-background-pressed"; 34 | } 35 | } 36 | } 37 | 38 | MouseArea { 39 | id: mouseArea; 40 | anchors.fill: parent; 41 | onClicked: { 42 | if (root.ListView.view){ 43 | root.ListView.view.currentIndex = index; 44 | } 45 | root.clicked(); 46 | } 47 | onPressAndHold: root.pressAndHold(); 48 | onPressed: if (highlightLoader.status == Loader.Null) 49 | highlightLoader.sourceComponent = highlightComp; 50 | } 51 | 52 | NumberAnimation { 53 | id: onAddAnimation 54 | target: root 55 | property: "opacity" 56 | duration: 250 57 | from: 0.25; to: 1; 58 | } 59 | 60 | ListView.onAdd: { 61 | onAddAnimation.start(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /qml/gfx/clock.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 19 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/utility.h: -------------------------------------------------------------------------------- 1 | #ifndef UTILITY_H 2 | #define UTILITY_H 3 | 4 | #include 5 | 6 | class Utility : public QObject 7 | { 8 | Q_OBJECT 9 | Q_PROPERTY(QString appVersion READ appVersion CONSTANT) 10 | Q_PROPERTY(int qtVersion READ qtVersion CONSTANT) 11 | public: 12 | static Utility* Instance(); 13 | ~Utility(); 14 | 15 | QString appVersion() const; 16 | int qtVersion() const; 17 | 18 | public: 19 | // Save and load settings. 20 | Q_INVOKABLE QVariant getValue(const QString &key, const QVariant defaultValue = QVariant()); 21 | Q_INVOKABLE void setValue(const QString &key, const QVariant &value); 22 | 23 | // Clear network cookies in qml 24 | Q_INVOKABLE void clearCookies(); 25 | 26 | // Get url parameters 27 | Q_INVOKABLE QString urlQueryItemValue(const QString &url, const QString &key) const; 28 | 29 | // Launch player using built-in player 30 | Q_INVOKABLE void launchPlayer(const QString &url); 31 | 32 | // Share links using share ui 33 | Q_INVOKABLE void share(const QString &title, const QString &link); 34 | 35 | // Open html using default browser 36 | Q_INVOKABLE void openHtml(const QString &html); 37 | 38 | // Make date readable 39 | Q_INVOKABLE QString easyDate(const QDateTime &date); 40 | 41 | // Parse XML text 42 | Q_INVOKABLE QString domNodeValue(const QString &data, const QString &tagName); 43 | 44 | // Launch built-in browser 45 | Q_INVOKABLE void openURLDefault(const QString &url); 46 | 47 | private: 48 | explicit Utility(QObject *parent = 0); 49 | 50 | QSettings* settings; 51 | QVariantMap map; 52 | 53 | QHash lang; 54 | QList formats; 55 | void initializeLangFormats(); 56 | int normalize(int val, int single); 57 | 58 | #ifdef Q_OS_SYMBIAN 59 | void LaunchAppL(const TUid aUid, HBufC* aParam); 60 | void LaunchL(int id, const QString& param); 61 | bool Launch(const int id, const QString& param); 62 | #endif 63 | }; 64 | 65 | #endif // UTILITY_H 66 | -------------------------------------------------------------------------------- /qml/AcFun/Component/AbstractItem.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | property bool platformInverted: false; 8 | property alias paddingItem: paddingItem; 9 | 10 | signal clicked; 11 | signal pressAndHold; 12 | 13 | implicitWidth: ListView.view ? ListView.view.width : 0; 14 | implicitHeight: platformStyle.graphicSizeLarge; 15 | 16 | Item { 17 | id: paddingItem; 18 | anchors { 19 | left: parent.left; leftMargin: platformStyle.paddingLarge; 20 | right: parent.right; rightMargin: platformStyle.paddingLarge; 21 | top: parent.top; topMargin: platformStyle.paddingLarge; 22 | bottom: parent.bottom; bottomMargin: platformStyle.paddingLarge; 23 | } 24 | } 25 | 26 | Rectangle { 27 | id: bottomLine; 28 | anchors { 29 | left: root.left; right: root.right; bottom: parent.bottom; 30 | } 31 | height: 1; 32 | color: root.platformInverted ? platformStyle.colorDisabledLightInverted 33 | : platformStyle.colorDisabledMid; 34 | } 35 | 36 | MouseArea { 37 | anchors.fill: parent; 38 | enabled: root.enabled; 39 | onClicked: { 40 | root.ListView.view.currentIndex = index; 41 | root.clicked(); 42 | } 43 | onPressed: { 44 | privateStyle.play(Symbian.BasicItem); 45 | root.opacity = 0.7; 46 | } 47 | onReleased: { 48 | privateStyle.play(Symbian.BasicItem); 49 | root.opacity = 1 50 | } 51 | onCanceled: { 52 | root.opacity = 1; 53 | } 54 | onPressAndHold: root.pressAndHold(); 55 | } 56 | 57 | NumberAnimation { 58 | id: onAddAnimation 59 | target: root 60 | property: "opacity" 61 | duration: 250 62 | from: 0.25; to: 1; 63 | } 64 | 65 | ListView.onAdd: { 66 | onAddAnimation.start(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/util.js: -------------------------------------------------------------------------------- 1 | .pragma library 2 | 3 | function milliSecondsToString(milliseconds) { 4 | milliseconds = milliseconds > 0 ? milliseconds : 0; 5 | var timeInSeconds = Math.floor(milliseconds / 1000); 6 | var minutes = Math.floor(timeInSeconds / 60); 7 | var minutesString = minutes < 10 ? "0" + minutes : minutes; 8 | var seconds = Math.floor(timeInSeconds % 60); 9 | var secondsString = seconds < 10 ? "0" + seconds : seconds; 10 | return minutesString + ":" + secondsString; 11 | } 12 | 13 | function secondsToString(seconds) { 14 | return milliSecondsToString(seconds*1000); 15 | } 16 | 17 | function formatDate(dateString) { 18 | // Split the given dateString. 19 | // It's formatted in ISO 8601 (such as 2000-01-01T12:00:00.000Z). 20 | var dateStr = dateString.substring(0, 10); 21 | var timeStr = dateString.substring(11, dateString.length-1); 22 | 23 | var date = convertToDate(dateStr, timeStr); 24 | return date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear(); 25 | } 26 | 27 | function convertToDate(date, time) { 28 | // "Constant" definition. Define for the parseInt to use decimal system. 29 | var RADIX = 10; 30 | 31 | // Convert ISO 8601 representation of date to JS Date. 32 | var newDate = new Date(parseInt(date.substr(0,4), RADIX), // Parses the year (4 digits) 33 | parseInt(date.substr(5,2), RADIX)-1,// Parses the month (2 digits) 34 | parseInt(date.substr(8,2), RADIX)); // Parses the day (2 digits) 35 | // If time was given, add it as well. 36 | if(time) { 37 | // Set hours, 0-11 38 | newDate.setHours(parseInt(time.substr(0,2), RADIX)); 39 | // Set minutes, 0-59 40 | newDate.setMinutes(parseInt(time.substr(3,2), RADIX)); 41 | // Set seconds, 0-59 42 | newDate.setSeconds(parseInt(time.substr(6,2), RADIX)); 43 | // Set milliseconds, 0-999 44 | newDate.setMilliseconds(parseInt(time.substr(9,2), RADIX)); 45 | } 46 | 47 | return newDate; 48 | } 49 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/util.js: -------------------------------------------------------------------------------- 1 | .pragma library 2 | 3 | function milliSecondsToString(milliseconds) { 4 | milliseconds = milliseconds > 0 ? milliseconds : 0; 5 | var timeInSeconds = Math.floor(milliseconds / 1000); 6 | var minutes = Math.floor(timeInSeconds / 60); 7 | var minutesString = minutes < 10 ? "0" + minutes : minutes; 8 | var seconds = Math.floor(timeInSeconds % 60); 9 | var secondsString = seconds < 10 ? "0" + seconds : seconds; 10 | return minutesString + ":" + secondsString; 11 | } 12 | 13 | function secondsToString(seconds) { 14 | return milliSecondsToString(seconds*1000); 15 | } 16 | 17 | function formatDate(dateString) { 18 | // Split the given dateString. 19 | // It's formatted in ISO 8601 (such as 2000-01-01T12:00:00.000Z). 20 | var dateStr = dateString.substring(0, 10); 21 | var timeStr = dateString.substring(11, dateString.length-1); 22 | 23 | var date = convertToDate(dateStr, timeStr); 24 | return date.getDate() + "/" + date.getMonth() + "/" + date.getFullYear(); 25 | } 26 | 27 | function convertToDate(date, time) { 28 | // "Constant" definition. Define for the parseInt to use decimal system. 29 | var RADIX = 10; 30 | 31 | // Convert ISO 8601 representation of date to JS Date. 32 | var newDate = new Date(parseInt(date.substr(0,4), RADIX), // Parses the year (4 digits) 33 | parseInt(date.substr(5,2), RADIX)-1,// Parses the month (2 digits) 34 | parseInt(date.substr(8,2), RADIX)); // Parses the day (2 digits) 35 | // If time was given, add it as well. 36 | if(time) { 37 | // Set hours, 0-11 38 | newDate.setHours(parseInt(time.substr(0,2), RADIX)); 39 | // Set minutes, 0-59 40 | newDate.setMinutes(parseInt(time.substr(3,2), RADIX)); 41 | // Set seconds, 0-59 42 | newDate.setSeconds(parseInt(time.substr(6,2), RADIX)); 43 | // Set milliseconds, 0-999 44 | newDate.setMilliseconds(parseInt(time.substr(9,2), RADIX)); 45 | } 46 | 47 | return newDate; 48 | } 49 | -------------------------------------------------------------------------------- /qml/AcFun/Component/SearchInput.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | TextField { 5 | id: root; 6 | 7 | signal typeStopped; 8 | signal cleared; 9 | 10 | onTextChanged: { 11 | inputTimer.restart(); 12 | } 13 | 14 | platformLeftMargin: searchIcon.width + platformStyle.paddingMedium; 15 | platformRightMargin: clearButton.width + platformStyle.paddingMedium; 16 | 17 | Timer { 18 | id: inputTimer; 19 | interval: 500; 20 | onTriggered: root.typeStopped(); 21 | } 22 | 23 | Image { 24 | id: searchIcon; 25 | anchors { left: parent.left; leftMargin: platformStyle.paddingMedium; verticalCenter: parent.verticalCenter; } 26 | height: platformStyle.graphicSizeSmall; 27 | width: platformStyle.graphicSizeSmall; 28 | sourceSize: Qt.size(platformStyle.graphicSizeSmall, platformStyle.graphicSizeSmall); 29 | source: privateStyle.toolBarIconPath("toolbar-search", true); 30 | } 31 | 32 | Item { 33 | id: clearButton; 34 | anchors { right: parent.right; rightMargin: platformStyle.paddingMedium; verticalCenter: parent.verticalCenter; } 35 | height: platformStyle.graphicSizeSmall; 36 | width: platformStyle.graphicSizeSmall; 37 | opacity: root.activeFocus ? 1 : 0; 38 | Behavior on opacity { 39 | NumberAnimation { duration: 100; } 40 | } 41 | Image { 42 | anchors.fill: parent; 43 | sourceSize: Qt.size(platformStyle.graphicSizeSmall, platformStyle.graphicSizeSmall); 44 | source: privateStyle.imagePath(clearMouseArea.pressed?"qtg_graf_textfield_clear_pressed":"qtg_graf_textfield_clear_normal", root.platformInverted); 45 | } 46 | MouseArea { 47 | id: clearMouseArea; 48 | anchors.fill: parent; 49 | onClicked: { 50 | root.closeSoftwareInputPanel(); 51 | root.text = ""; 52 | root.cleared(); 53 | root.parent.forceActiveFocus(); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /qml/gfx/ok.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 14 | 18 | 21 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /qml/harmattan/SeriesPageCom/SeriesDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root; 5 | 6 | implicitWidth: GridView.view.cellWidth; 7 | implicitHeight: GridView.view.cellHeight; 8 | 9 | Image { 10 | id: preview; 11 | anchors { 12 | left: parent.left; right: parent.right; 13 | top: parent.top; margins: constant.paddingSmall; 14 | } 15 | height: width*4/3; 16 | sourceSize.width: 160; 17 | source: model.cover; 18 | fillMode: Image.PreserveAspectFit; 19 | } 20 | 21 | Rectangle { 22 | anchors { 23 | left: preview.left; right: preview.right; 24 | bottom: preview.bottom; 25 | } 26 | height: constant.titleFont.pixelSize; 27 | color: "#801f1f1f"; 28 | Text { 29 | anchors.fill: parent; 30 | font { pixelSize: constant.subTitleFont.pixelSize-2; } 31 | color: "white"; 32 | text: model.subhead 33 | horizontalAlignment: Text.AlignRight; 34 | verticalAlignment: Text.AlignVCenter; 35 | elide: Text.ElideRight; 36 | wrapMode: Text.Wrap; 37 | maximumLineCount: 1; 38 | textFormat: Text.PlainText; 39 | } 40 | } 41 | 42 | Text { 43 | id: label; 44 | anchors { 45 | left: parent.left; right: parent.right; 46 | top: preview.bottom; bottom: parent.bottom; 47 | } 48 | horizontalAlignment: Text.AlignHCenter; 49 | verticalAlignment: Text.AlignVCenter; 50 | elide: Text.ElideRight; 51 | wrapMode: Text.Wrap; 52 | maximumLineCount: 1; 53 | textFormat: Text.PlainText; 54 | text: model.title; 55 | font: constant.subTitleFont; 56 | color: constant.colorLight; 57 | } 58 | 59 | Rectangle { 60 | anchors.fill: parent; 61 | color: "black"; 62 | opacity: mouseArea.pressed ? 0.3 : 0; 63 | } 64 | 65 | MouseArea { 66 | id: mouseArea; 67 | anchors.fill: parent; 68 | onClicked: pageStack.push(Qt.resolvedUrl("SeriesDetailPage.qml"), 69 | {acId: model.id}); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /qml/AcFun/SeriesPageCom/SeriesDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root; 5 | 6 | implicitWidth: GridView.view.cellWidth; 7 | implicitHeight: GridView.view.cellHeight; 8 | 9 | Image { 10 | id: preview; 11 | anchors { 12 | left: parent.left; right: parent.right; 13 | top: parent.top; margins: constant.paddingSmall; 14 | } 15 | height: width*4/3; 16 | sourceSize.width: 120; 17 | source: model.cover; 18 | fillMode: Image.PreserveAspectFit; 19 | } 20 | 21 | Rectangle { 22 | anchors { 23 | left: preview.left; right: preview.right; 24 | bottom: preview.bottom; 25 | } 26 | height: platformStyle.fontSizeLarge; 27 | color: "#801f1f1f"; 28 | Text { 29 | anchors.fill: parent; 30 | font { pixelSize: constant.subTitleFont.pixelSize-2; } 31 | color: constant.colorLight; 32 | text: model.subhead 33 | horizontalAlignment: Text.AlignRight; 34 | verticalAlignment: Text.AlignVCenter; 35 | elide: Text.ElideRight; 36 | wrapMode: Text.Wrap; 37 | maximumLineCount: 1; 38 | textFormat: Text.PlainText; 39 | } 40 | } 41 | 42 | Text { 43 | id: label; 44 | anchors { 45 | left: parent.left; right: parent.right; 46 | top: preview.bottom; bottom: parent.bottom; 47 | } 48 | horizontalAlignment: Text.AlignHCenter; 49 | verticalAlignment: Text.AlignVCenter; 50 | elide: Text.ElideRight; 51 | wrapMode: Text.Wrap; 52 | maximumLineCount: 1; 53 | textFormat: Text.PlainText; 54 | text: model.title; 55 | font: constant.subTitleFont; 56 | color: constant.colorLight; 57 | } 58 | 59 | Rectangle { 60 | anchors.fill: parent; 61 | color: "black"; 62 | opacity: mouseArea.pressed ? 0.3 : 0; 63 | } 64 | 65 | MouseArea { 66 | id: mouseArea; 67 | anchors.fill: parent; 68 | onClicked: pageStack.push(Qt.resolvedUrl("SeriesDetailPage.qml"), 69 | {acId: model.id}); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /qml/AcFun/SignalCenter.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | QtObject { 4 | id: signalCenter; 5 | 6 | signal userChanged; 7 | signal initialized; 8 | 9 | property variant videocategories: []; 10 | property variant queryDialogComp: null; 11 | 12 | function showMessage(msg){ 13 | if (msg||false){ 14 | infoBanner.text = msg; 15 | infoBanner.open(); 16 | } 17 | } 18 | 19 | function viewDetail(vid, cid){ 20 | var id; 21 | if (typeof(vid) === "number"){ 22 | id = vid; 23 | } else if (typeof(vid) === "string"){ 24 | var tmp = vid.match(/(videoinfo\?id=ac|\b)(\d+)\b/); 25 | if (tmp) id = tmp[2]; 26 | else return; 27 | } 28 | var prop = {"acId": id}; 29 | if (cid==63||cid==73||cid==110||cid==75||cid==74||cid==76){ 30 | // article 31 | pageStack.push(Qt.resolvedUrl("VideoDetailCom/ArticlePage.qml"), prop); 32 | } else if (cid==71){ 33 | // flash 34 | pageStack.push(Qt.resolvedUrl("VideoDetailCom/OldDetailPage.qml"), prop); 35 | } else { 36 | pageStack.push(Qt.resolvedUrl("VideoDetailPage.qml"), prop); 37 | } 38 | } 39 | 40 | function playVideo(acId, type, sid, cid){ 41 | console.log("play video==============\n", acId, type, sid, cid); 42 | var prop = { acId: acId, type: type, sid: sid, cid: cid }; 43 | var p = pageStack.push(Qt.resolvedUrl("VideoPage.qml"), prop, true); 44 | p.load(); 45 | } 46 | 47 | function login(){ 48 | pageStack.push(Qt.resolvedUrl("LoginPage.qml")); 49 | } 50 | 51 | function createQueryDialog(title, message, acceptText, rejectText, acceptCallback, rejectCallback){ 52 | if (!queryDialogComp){ queryDialogComp = Qt.createComponent("Component/DynamicQueryDialog.qml"); } 53 | var prop = { titleText: title, message: message.concat("\n"), acceptButtonText: acceptText, rejectButtonText: rejectText }; 54 | var diag = queryDialogComp.createObject(pageStack.currentPage, prop); 55 | if (acceptCallback) diag.accepted.connect(acceptCallback); 56 | if (rejectCallback) diag.rejected.connect(rejectCallback); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /qml/AcFun/Component/StatusPaneText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Row { 5 | id: root; 6 | 7 | property string text: "AcFun"; 8 | 9 | opacity: app.showStatusBar ? 1 : 0; 10 | anchors { left: parent.left; top: parent.top; } 11 | 12 | // Busy indicator. 13 | BusyIndicator { 14 | id: busyIndicator; 15 | width: privateStyle.statusBarHeight; 16 | height: privateStyle.statusBarHeight; 17 | running: true; 18 | visible: pageStack.currentPage.loading || false; 19 | } 20 | 21 | // To scroll the text. 22 | Flickable { 23 | id: scrollingTitle; 24 | clip: true; 25 | interactive: false; 26 | height: privateStyle.statusBarHeight; 27 | width: screen.width - 200; 28 | 29 | contentWidth: Math.max(statusPaneTitle.width, width); 30 | contentHeight: privateStyle.statusBarHeight; 31 | 32 | onWidthChanged: resetAnimation(); 33 | 34 | function resetAnimation(){ 35 | scrollingAnimation.complete(); 36 | if (statusPaneTitle.width > scrollingTitle.width){ 37 | scrolling.to = statusPaneTitle.width - scrollingTitle.width; 38 | scrollingAnimation.start(); 39 | } 40 | } 41 | 42 | Label { 43 | id: statusPaneTitle; 44 | height: parent.height; 45 | verticalAlignment: Text.AlignVCenter; 46 | font.pixelSize: platformStyle.fontSizeSmall; 47 | textFormat: Text.PlainText; 48 | onTextChanged: scrollingTitle.resetAnimation(); 49 | text: root.text; 50 | } 51 | 52 | SequentialAnimation { 53 | id: scrollingAnimation; 54 | PropertyAction { target: scrollingTitle; property: "contentX"; value: 0; } 55 | PauseAnimation { duration: 1000; } 56 | PropertyAnimation { 57 | id: scrolling; 58 | target: scrollingTitle; 59 | property: "contentX"; 60 | duration: to*30; 61 | } 62 | PauseAnimation { duration: 1000; } 63 | PropertyAnimation { target: scrollingTitle; property: "contentX"; to: 0; } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /qml/harmattan/Component/StatusPaneText.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Row { 5 | id: root; 6 | 7 | property string text: "AcFun"; 8 | 9 | opacity: app.showStatusBar ? 1 : 0; 10 | anchors { left: parent.left; top: parent.top; } 11 | 12 | // Busy indicator. 13 | BusyIndicator { 14 | id: busyIndicator; 15 | width: privateStyle.statusBarHeight; 16 | height: privateStyle.statusBarHeight; 17 | running: true; 18 | visible: pageStack.currentPage.loading || false; 19 | } 20 | 21 | // To scroll the text. 22 | Flickable { 23 | id: scrollingTitle; 24 | clip: true; 25 | interactive: false; 26 | height: privateStyle.statusBarHeight; 27 | width: screen.width - 200; 28 | 29 | contentWidth: Math.max(statusPaneTitle.width, width); 30 | contentHeight: privateStyle.statusBarHeight; 31 | 32 | onWidthChanged: resetAnimation(); 33 | 34 | function resetAnimation(){ 35 | scrollingAnimation.complete(); 36 | if (statusPaneTitle.width > scrollingTitle.width){ 37 | scrolling.to = statusPaneTitle.width - scrollingTitle.width; 38 | scrollingAnimation.start(); 39 | } 40 | } 41 | 42 | Label { 43 | id: statusPaneTitle; 44 | height: parent.height; 45 | verticalAlignment: Text.AlignVCenter; 46 | font.pixelSize: platformStyle.fontSizeSmall; 47 | textFormat: Text.PlainText; 48 | onTextChanged: scrollingTitle.resetAnimation(); 49 | text: root.text; 50 | } 51 | 52 | SequentialAnimation { 53 | id: scrollingAnimation; 54 | PropertyAction { target: scrollingTitle; property: "contentX"; value: 0; } 55 | PauseAnimation { duration: 1000; } 56 | PropertyAnimation { 57 | id: scrolling; 58 | target: scrollingTitle; 59 | property: "contentX"; 60 | duration: to*30; 61 | } 62 | PauseAnimation { duration: 1000; } 63 | PropertyAnimation { target: scrollingTitle; property: "contentX"; to: 0; } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /qml/js/IQiyiParser.js: -------------------------------------------------------------------------------- 1 | var IQiyiParser = new Function(); 2 | IQiyiParser.prototype = new VideoParser(); 3 | IQiyiParser.prototype.constructor = IQiyiParser; 4 | IQiyiParser.prototype.name = "爱奇艺"; 5 | 6 | IQiyiParser.prototype.start = function(vid){ 7 | var resultUrl = ""; 8 | 9 | var url = "http://cache.m.iqiyi.com/jp/tmts/272448000/1ed6cc39cdcfeb2f3d9156a6f1b8943e/"; 10 | var now = Date.now(); 11 | var param = { 12 | "uid": "", 13 | "cupid": "qc_100001_100102", 14 | "platForm": "h5", 15 | "type": "mp4", 16 | "rate": "1", 17 | "src": "d846d0c32d664d32b6b54ea48997a589", 18 | "sc": "921359bdda1f665ecbf14842b2222f5f", 19 | "__refI": "", 20 | "__ctmM": now, 21 | "t": now, 22 | "__jsT": "sijsc", 23 | "callback": "QVCallback" 24 | } 25 | var paramList = []; 26 | for (var i in param){ 27 | paramList.push(i + "=" + param[i]); 28 | } 29 | url += "?" + paramList.join("&"); 30 | var QVCallback = function(obj){ 31 | if (obj && obj.code && obj.code == "A00000"){ 32 | resultUrl = obj.data.m3u; 33 | } 34 | } 35 | var xhr = new XMLHttpRequest(); 36 | xhr.onreadystatechange = function(){ 37 | if (xhr.readyState == XMLHttpRequest.DONE){ 38 | if (xhr.status == 200){ 39 | try { 40 | eval(xhr.responseText); 41 | if (typeof(resultUrl) == "string" && resultUrl != ""){ 42 | IQiyiParser.prototype.success(resultUrl); 43 | return; 44 | } 45 | } catch (e){ 46 | } 47 | } 48 | IQiyiParser.prototype.error(); 49 | } 50 | } 51 | xhr.open("GET", url); 52 | xhr.send(); 53 | } 54 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | 14 | 15 | 16 | configure: configure-stamp 17 | configure-stamp: 18 | dh_testdir 19 | # qmake PREFIX=/usr# Uncomment this line for use without Qt Creator 20 | 21 | touch configure-stamp 22 | 23 | 24 | build: build-stamp 25 | 26 | build-stamp: configure-stamp 27 | dh_testdir 28 | 29 | # Add here commands to compile the package. 30 | # $(MAKE) # Uncomment this line for use without Qt Creator 31 | #docbook-to-man debian/acfun.sgml > acfun.1 32 | 33 | touch $@ 34 | 35 | clean: 36 | dh_testdir 37 | dh_testroot 38 | rm -f build-stamp configure-stamp 39 | 40 | # Add here commands to clean up after the build process. 41 | $(MAKE) clean 42 | 43 | dh_clean 44 | 45 | install: build 46 | dh_testdir 47 | dh_testroot 48 | dh_clean -k 49 | dh_installdirs 50 | 51 | # Add here commands to install the package into debian/acfun. 52 | $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/acfun install 53 | 54 | 55 | # Build architecture-independent files here. 56 | binary-indep: build install 57 | # We have nothing to do by default. 58 | 59 | # Build architecture-dependent files here. 60 | binary-arch: build install 61 | dh_testdir 62 | dh_testroot 63 | dh_installchangelogs 64 | dh_installdocs 65 | dh_installexamples 66 | # dh_install 67 | # dh_installmenu 68 | # dh_installdebconf 69 | # dh_installlogrotate 70 | # dh_installemacsen 71 | # dh_installpam 72 | # dh_installmime 73 | # dh_python 74 | # dh_installinit 75 | # dh_installcron 76 | # dh_installinfo 77 | dh_installman 78 | dh_link 79 | dh_strip 80 | dh_compress 81 | dh_fixperms 82 | # dh_perl 83 | # dh_makeshlibs 84 | dh_installdeb 85 | dh_shlibdeps # Uncomment this line for use without Qt Creator 86 | dh_gencontrol 87 | dh_md5sums 88 | dh_builddeb 89 | 90 | binary: binary-indep binary-arch 91 | .PHONY: build clean binary-indep binary-arch binary install configure 92 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | 14 | 15 | 16 | configure: configure-stamp 17 | configure-stamp: 18 | dh_testdir 19 | # qmake PREFIX=/usr# Uncomment this line for use without Qt Creator 20 | 21 | touch configure-stamp 22 | 23 | 24 | build: build-stamp 25 | 26 | build-stamp: configure-stamp 27 | dh_testdir 28 | 29 | # Add here commands to compile the package. 30 | # $(MAKE) # Uncomment this line for use without Qt Creator 31 | #docbook-to-man debian/acfun.sgml > acfun.1 32 | 33 | touch $@ 34 | 35 | clean: 36 | dh_testdir 37 | dh_testroot 38 | rm -f build-stamp configure-stamp 39 | 40 | # Add here commands to clean up after the build process. 41 | $(MAKE) clean 42 | 43 | dh_clean 44 | 45 | install: build 46 | dh_testdir 47 | dh_testroot 48 | dh_clean -k 49 | dh_installdirs 50 | 51 | # Add here commands to install the package into debian/acfun. 52 | $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/acfun install 53 | 54 | 55 | # Build architecture-independent files here. 56 | binary-indep: build install 57 | # We have nothing to do by default. 58 | 59 | # Build architecture-dependent files here. 60 | binary-arch: build install 61 | dh_testdir 62 | dh_testroot 63 | dh_installchangelogs 64 | dh_installdocs 65 | dh_installexamples 66 | # dh_install 67 | # dh_installmenu 68 | # dh_installdebconf 69 | # dh_installlogrotate 70 | # dh_installemacsen 71 | # dh_installpam 72 | # dh_installmime 73 | # dh_python 74 | # dh_installinit 75 | # dh_installcron 76 | # dh_installinfo 77 | dh_installman 78 | dh_link 79 | dh_strip 80 | dh_compress 81 | dh_fixperms 82 | # dh_perl 83 | # dh_makeshlibs 84 | dh_installdeb 85 | # dh_shlibdeps # Uncomment this line for use without Qt Creator 86 | dh_gencontrol 87 | dh_md5sums 88 | dh_builddeb 89 | 90 | binary: binary-indep binary-arch 91 | .PHONY: build clean binary-indep binary-arch binary install configure 92 | -------------------------------------------------------------------------------- /qml/gfx/send.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 16 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /qml/harmattan/Component/CommonDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | AbstractItem { 4 | id: root; 5 | implicitHeight: 120 + constant.paddingLarge*2; 6 | onClicked: signalCenter.viewDetail(model.acId); 7 | Image { 8 | id: preview; 9 | anchors { 10 | left: root.paddingItem.left; 11 | top: root.paddingItem.top; 12 | bottom: root.paddingItem.bottom; 13 | } 14 | width: 160; 15 | sourceSize.width: 160; 16 | source: model.previewurl 17 | } 18 | Text { 19 | anchors { 20 | left: preview.right; leftMargin: constant.paddingMedium; 21 | right: root.paddingItem.right; top: root.paddingItem.top; 22 | } 23 | elide: Text.ElideRight; 24 | wrapMode: Text.Wrap; 25 | maximumLineCount: 2; 26 | textFormat: Text.PlainText; 27 | font: constant.titleFont; 28 | color: constant.colorLight; 29 | text: model.name; 30 | } 31 | Row { 32 | anchors { 33 | left: preview.right; leftMargin: constant.paddingMedium; 34 | right: root.paddingItem.right; bottom: root.paddingItem.bottom; 35 | } 36 | spacing: constant.paddingSmall; 37 | Image { 38 | anchors.verticalCenter: parent.verticalCenter; 39 | sourceSize: Qt.size(constant.graphicSizeTiny, 40 | constant.graphicSizeTiny); 41 | source: "../../gfx/image_upman_small.png"; 42 | } 43 | Text { 44 | anchors.verticalCenter: parent.verticalCenter; 45 | width: parent.width / 2; 46 | font: constant.subTitleFont; 47 | color: constant.colorMid; 48 | text: model.creatorName; 49 | elide: Text.ElideRight; 50 | } 51 | Image { 52 | anchors.verticalCenter: parent.verticalCenter; 53 | sourceSize: Qt.size(constant.graphicSizeTiny, 54 | constant.graphicSizeTiny); 55 | source: "../../gfx/image_watches_small.png"; 56 | } 57 | Text { 58 | anchors.verticalCenter: parent.verticalCenter; 59 | font: constant.subTitleFont; 60 | color: constant.colorMid; 61 | text: model.viewernum; 62 | elide: Text.ElideRight; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /qml/AcFun/Component/CommonDelegate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | AbstractItem { 4 | id: root; 5 | implicitHeight: 90 + constant.paddingLarge*2; 6 | onClicked: signalCenter.viewDetail(model.acId, model.channelId); 7 | Image { 8 | id: preview; 9 | anchors { 10 | left: root.paddingItem.left; 11 | top: root.paddingItem.top; 12 | bottom: root.paddingItem.bottom; 13 | } 14 | width: 120; 15 | sourceSize.width: 120; 16 | source: model.previewurl 17 | } 18 | Text { 19 | anchors { 20 | left: preview.right; leftMargin: constant.paddingMedium; 21 | right: root.paddingItem.right; top: root.paddingItem.top; 22 | } 23 | elide: Text.ElideRight; 24 | wrapMode: Text.Wrap; 25 | maximumLineCount: 2; 26 | textFormat: Text.PlainText; 27 | font: constant.titleFont; 28 | color: constant.colorLight; 29 | text: model.name; 30 | } 31 | Row { 32 | anchors { 33 | left: preview.right; leftMargin: constant.paddingMedium; 34 | right: root.paddingItem.right; bottom: root.paddingItem.bottom; 35 | } 36 | spacing: constant.paddingSmall; 37 | Image { 38 | anchors.verticalCenter: parent.verticalCenter; 39 | sourceSize: Qt.size(constant.graphicSizeTiny, 40 | constant.graphicSizeTiny); 41 | source: "../../gfx/image_upman_small.png"; 42 | } 43 | Text { 44 | anchors.verticalCenter: parent.verticalCenter; 45 | width: parent.width / 2; 46 | font: constant.subTitleFont; 47 | color: constant.colorMid; 48 | text: model.creatorName; 49 | elide: Text.ElideRight; 50 | } 51 | Image { 52 | anchors.verticalCenter: parent.verticalCenter; 53 | sourceSize: Qt.size(constant.graphicSizeTiny, 54 | constant.graphicSizeTiny); 55 | source: "../../gfx/image_watches_small.png"; 56 | } 57 | Text { 58 | anchors.verticalCenter: parent.verticalCenter; 59 | font: constant.subTitleFont; 60 | color: constant.colorMid; 61 | text: model.viewernum; 62 | elide: Text.ElideRight; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/ACPlayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root; 5 | 6 | // 视频源地址 7 | property url source; 8 | onSourceChanged: if (videoPlayer) videoPlayer.source = source; 9 | // 弹幕池ID 10 | property string commentId; 11 | // 播放器层接口 12 | property alias videoPlayer: videoPlayerLoader.item; 13 | 14 | signal playStarted; 15 | signal exit; 16 | 17 | function __slotLoadStarted(){ 18 | //开始加载视频,同时加载评论 19 | commentLayerLoader.sourceComponent = commentLayerComp; 20 | } 21 | function __handleExit(){ 22 | if (videoPlayer) videoPlayer.stop(); 23 | root.exit(); 24 | } 25 | 26 | anchors.fill: parent; 27 | 28 | // 播放器层加载器 29 | Loader { 30 | id: videoPlayerLoader; 31 | anchors.fill: parent; 32 | } 33 | 34 | // 延时加载播放器层,防止页面切换时出现卡顿 35 | Timer { 36 | id: playerLoadTimer; 37 | running: true; 38 | interval: visual.animationDurationPrettyLong; 39 | onTriggered: { 40 | stop(); 41 | videoPlayerLoader.sourceComponent = 42 | Qt.createComponent("VideoLayer.qml"); 43 | if (videoPlayerLoader.status === Loader.Ready){ 44 | videoPlayer.loadStarted.connect(__slotLoadStarted); 45 | videoPlayer.playbackStarted.connect(playStarted); 46 | videoPlayer.source = root.source; 47 | } 48 | } 49 | } 50 | 51 | // 评论层加载器 52 | Loader { 53 | id: commentLayerLoader; 54 | anchors.fill: parent; 55 | } 56 | // 评论层组件 57 | Component { 58 | id: commentLayerComp; 59 | CommentLayer { 60 | id: commentLayer; 61 | timePlayed: videoPlayer.timePlayed; 62 | commentId: root.commentId; 63 | } 64 | } 65 | 66 | // 控制器层 67 | ControlLayer { 68 | id: controlLayer; 69 | autoHide: videoPlayer !== null && videoPlayer.isPlaying; 70 | timePlayed: videoPlayer ? videoPlayer.timePlayed : 0; 71 | timeDuration: videoPlayer ? videoPlayer.duration : 0; 72 | isPlaying: videoPlayer ? videoPlayer.isPlaying : false; 73 | backFreezed: videoPlayer ? videoPlayer.freezing : false; 74 | onBackPressed: __handleExit(); 75 | onPausePressed: if(videoPlayer)videoPlayer.pause(); 76 | onPlayPressed: if(videoPlayer)videoPlayer.play(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /qml/AcFun/SearchPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | title: "搜索"; 10 | 11 | tools: ToolBarLayout { 12 | ToolButton { 13 | iconSource: "toolbar-back"; 14 | onClicked: pageStack.pop(); 15 | } 16 | } 17 | 18 | onStatusChanged: { 19 | if (status === PageStatus.Active){ 20 | searchInput.forceActiveFocus(); 21 | searchInput.openSoftwareInputPanel(); 22 | getlist(); 23 | } 24 | } 25 | 26 | function getlist(){ 27 | loading = true; 28 | function s(){ loading = false; } 29 | function f(err){ loading = false; signalCenter.showMessage(err); } 30 | Script.getHotkeys(view.model, s, f); 31 | } 32 | 33 | ViewHeader { 34 | id: viewHeader; 35 | 36 | SearchInput { 37 | id: searchInput; 38 | anchors { 39 | left: parent.left; right: searchBtn.left; 40 | margins: constant.paddingMedium; 41 | verticalCenter: parent.verticalCenter; 42 | } 43 | } 44 | 45 | Button { 46 | id: searchBtn; 47 | anchors { 48 | right: parent.right; rightMargin: constant.paddingMedium; 49 | verticalCenter: parent.verticalCenter; 50 | } 51 | text: "搜索"; 52 | platformInverted: true; 53 | onClicked: { 54 | if (searchInput.text.length === 0) return; 55 | var prop = { term: searchInput.text }; 56 | var page = pageStack.push(Qt.resolvedUrl("SearchResultPage.qml"), prop); 57 | page.getlist(); 58 | } 59 | } 60 | } 61 | 62 | ListView { 63 | id: view; 64 | anchors { fill: parent; topMargin: viewHeader.height; } 65 | model: ListModel {} 66 | delegate: AbstractItem { 67 | Text { 68 | anchors { left: parent.paddingItem.left; verticalCenter: parent.verticalCenter; } 69 | font: constant.titleFont; 70 | color: constant.colorLight; 71 | text: model.name; 72 | } 73 | onClicked: { 74 | searchInput.text = model.name; 75 | searchBtn.clicked(); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /qtc_packaging/debian_harmattan/manifest.aegis: -------------------------------------------------------------------------------- 1 | AutoGenerateAegisFile 2 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | 43 | 44 | 45 | 48 | 49 | 50 | 53 | 54 | 55 | 58 | 59 | 60 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /qml/AcFun/VideoPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "../js/videoSourceLoader.js" as VL 4 | 5 | Page { 6 | id: page; 7 | 8 | property string acId; //ac id; 9 | property string type; //source type; 10 | property string sid; //source id; 11 | property string cid; //comment id; 12 | 13 | orientationLock: PageOrientation.LockLandscape; 14 | onStatusChanged: { 15 | if (status === PageStatus.Activating){ 16 | app.showStatusBar = false; 17 | } 18 | } 19 | 20 | function load(){ 21 | VL.loadSource(type, sid, messageModel); 22 | } 23 | function exit(){ 24 | pageStack.pop(undefined, true); 25 | app.showStatusBar = true; 26 | } 27 | function createPlayer(url){ 28 | playerLoader.sourceComponent = Qt.createComponent("ACPlayer/ACPlayer.qml"); 29 | if (playerLoader.status === Loader.Ready){ 30 | var item = playerLoader.item; 31 | item.source = url; 32 | item.commentId = cid; 33 | item.playStarted.connect(hideMessage); 34 | item.exit.connect(exit); 35 | } else { 36 | console.log("Error: player is not ready"); 37 | } 38 | } 39 | function hideMessage(){ 40 | exitBtn.visible = false; 41 | messageModel.clear(); 42 | } 43 | 44 | Loader { 45 | id: playerLoader; 46 | anchors.fill: parent; 47 | } 48 | 49 | // return button 50 | Button { 51 | id: exitBtn; 52 | enabled: playerLoader.item === null || 53 | playerLoader.item.videoPlayer === null || 54 | !playerLoader.item.videoPlayer.freezing; 55 | anchors { 56 | right: parent.right; top: parent.top; 57 | margins: constant.paddingSmall; 58 | } 59 | width: height; 60 | iconSource: "../gfx/tb_close_stop.svg"; 61 | onClicked: exit(); 62 | } 63 | 64 | // messages 65 | Column { 66 | id: contentCol; 67 | anchors { 68 | left: parent.left; bottom: parent.bottom; 69 | margins: constant.paddingSmall; 70 | } 71 | spacing: constant.paddingSmall; 72 | Repeater { 73 | model: ListModel { id: messageModel; } 74 | Text { 75 | font: constant.labelFont; 76 | color: constant.colorLight; 77 | text: modelData; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /qml/AcFun/SeriesPageCom/WikiPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import CustomWebKit 1.0 4 | import "../Component" 5 | 6 | MyPage { 7 | id: page; 8 | 9 | title: webView.title; 10 | 11 | tools: ToolBarLayout { 12 | ToolButton { 13 | iconSource: "toolbar-back"; 14 | onClicked: pageStack.pop(); 15 | } 16 | ToolButton { 17 | iconSource: "toolbar-refresh"; 18 | enabled: webView.reload.enabled; 19 | onClicked: webView.reload.trigger(); 20 | } 21 | } 22 | 23 | function load(){ 24 | webView.url = "http://wiki.acfun.tv/index.php/里区索引"; 25 | } 26 | 27 | function handle(link){ 28 | var linkString = link.toString(); 29 | if (/http.*?\.swf\?.*?vid=/.test(linkString)){ 30 | //播放器地址 31 | var vid = utility.urlQueryItemValue(linkString, "vid"); 32 | if (vid !== ""){ 33 | var cid = utility.urlQueryItemValue(linkString, "cid"); 34 | if (cid === "") cid = vid; 35 | signalCenter.playVideo("", "sina", vid, cid); 36 | return; 37 | } 38 | } 39 | if (linkString.indexOf("http://wiki.acfun.tv")===0){ 40 | webView.url = linkString; 41 | return; 42 | } 43 | var acMatch = linkString.match(/http:\/\/.*?acfun\.tv\/v\/ac(\d+)/); 44 | if (acMatch){ 45 | var acId = acMatch[1]; 46 | signalCenter.viewDetail(acId); 47 | return; 48 | } 49 | Qt.openUrlExternally(linkString); 50 | } 51 | 52 | Flickable { 53 | id: view; 54 | anchors.fill: parent; 55 | clip: true; 56 | contentWidth: webView.width; 57 | contentHeight: webView.height; 58 | boundsBehavior: Flickable.StopAtBounds; 59 | WebView { 60 | id: webView; 61 | preferredWidth: view.width; 62 | preferredHeight: view.height; 63 | settings { autoLoadImages: false; } 64 | onLoadStarted: { 65 | page.loading = true; 66 | view.contentX = 0; 67 | view.contentY = 0; 68 | view.returnToBounds(); 69 | } 70 | onLoadFinished: page.loading = false; 71 | onLoadFailed: page.loading = false; 72 | onLinkClicked: handle(link); 73 | } 74 | } 75 | 76 | ScrollDecorator { flickableItem: view; } 77 | } 78 | -------------------------------------------------------------------------------- /qml/harmattan/SearchPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | tools: ToolBarLayout { 10 | ToolIcon { 11 | platformIconId: "toolbar-back"; 12 | onClicked: pageStack.pop(); 13 | } 14 | } 15 | 16 | onStatusChanged: { 17 | if (status === PageStatus.Active){ 18 | searchInput.forceActiveFocus(); 19 | searchInput.platformOpenSoftwareInputPanel(); 20 | getlist(); 21 | } 22 | } 23 | 24 | function getlist(){ 25 | loading = true; 26 | function s(){ loading = false; } 27 | function f(err){ loading = false; signalCenter.showMessage(err); } 28 | Script.getHotkeys(view.model, s, f); 29 | } 30 | 31 | ViewHeader { 32 | id: viewHeader; 33 | 34 | SearchInput { 35 | id: searchInput; 36 | anchors { 37 | left: parent.left; right: searchBtn.left; 38 | margins: constant.paddingMedium; 39 | verticalCenter: parent.verticalCenter; 40 | } 41 | } 42 | 43 | Button { 44 | id: searchBtn; 45 | anchors { 46 | right: parent.right; rightMargin: constant.paddingMedium; 47 | verticalCenter: parent.verticalCenter; 48 | } 49 | platformStyle: ButtonStyle { 50 | buttonWidth: buttonHeight*2; 51 | } 52 | text: "搜索"; 53 | onClicked: { 54 | if (searchInput.text.length === 0) return; 55 | var prop = { term: searchInput.text }; 56 | var page = pageStack.push(Qt.resolvedUrl("SearchResultPage.qml"), prop); 57 | page.getlist(); 58 | } 59 | } 60 | } 61 | 62 | ListView { 63 | id: view; 64 | anchors { fill: parent; topMargin: viewHeader.height; } 65 | model: ListModel {} 66 | delegate: AbstractItem { 67 | Text { 68 | anchors { left: parent.paddingItem.left; verticalCenter: parent.verticalCenter; } 69 | font: constant.titleFont; 70 | color: constant.colorLight; 71 | text: model.name; 72 | } 73 | onClicked: { 74 | searchInput.text = model.name; 75 | searchBtn.clicked(); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /qml/harmattan/SeriesPageCom/WikiPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import CustomWebKit 1.0 4 | import "../Component" 5 | 6 | MyPage { 7 | id: page; 8 | 9 | title: webView.title; 10 | 11 | tools: ToolBarLayout { 12 | ToolIcon { 13 | platformIconId: "toolbar-back"; 14 | onClicked: pageStack.pop(); 15 | } 16 | ToolIcon { 17 | platformIconId: "toolbar-refresh"; 18 | enabled: webView.reload.enabled; 19 | onClicked: webView.reload.trigger(); 20 | } 21 | } 22 | 23 | function load(){ 24 | webView.url = "http://wiki.acfun.tv/index.php/里区索引"; 25 | } 26 | 27 | function handle(link){ 28 | var linkString = link.toString(); 29 | if (/http.*?\.swf\?.*?vid=/.test(linkString)){ 30 | //播放器地址 31 | var vid = utility.urlQueryItemValue(linkString, "vid"); 32 | if (vid !== ""){ 33 | var cid = utility.urlQueryItemValue(linkString, "cid"); 34 | if (cid === "") cid = vid; 35 | signalCenter.playVideo("", "sina", vid, cid); 36 | return; 37 | } 38 | } 39 | if (linkString.indexOf("http://wiki.acfun.tv")===0){ 40 | webView.url = linkString; 41 | return; 42 | } 43 | var acMatch = linkString.match(/http:\/\/.*?acfun\.tv\/v\/ac(\d+)/); 44 | if (acMatch){ 45 | var acId = acMatch[1]; 46 | signalCenter.viewDetail(acId); 47 | return; 48 | } 49 | Qt.openUrlExternally(linkString); 50 | } 51 | 52 | Flickable { 53 | id: view; 54 | anchors.fill: parent; 55 | clip: true; 56 | contentWidth: webView.width; 57 | contentHeight: webView.height; 58 | boundsBehavior: Flickable.StopAtBounds; 59 | WebView { 60 | id: webView; 61 | preferredWidth: view.width; 62 | preferredHeight: view.height; 63 | settings { autoLoadImages: false; } 64 | onLoadStarted: { 65 | page.loading = true; 66 | view.contentX = 0; 67 | view.contentY = 0; 68 | view.returnToBounds(); 69 | } 70 | onLoadFinished: page.loading = false; 71 | onLoadFailed: page.loading = false; 72 | onLinkClicked: handle(link); 73 | } 74 | } 75 | 76 | ScrollDecorator { flickableItem: view; } 77 | } 78 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/CommentLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import "../../js/main.js" as Script 3 | import "Comments.js" as Utils 4 | 5 | Item { 6 | id: root; 7 | 8 | property string commentId; 9 | property int timePlayed; 10 | 11 | property int commentCount: 0; 12 | 13 | function get(){ 14 | var opt = { 15 | pool: Utils.commentPool, 16 | cid: commentId 17 | } 18 | function s(){ 19 | console.log("comment loaded"); 20 | root.timePlayedChanged.connect(createText); 21 | } 22 | function f(err){ 23 | console.log(err); 24 | } 25 | Script.getSyncComments(opt, s, f); 26 | } 27 | 28 | function createText(){ 29 | if (timePlayed === 0) Utils.commentIndex = 0; 30 | var secs = timePlayed / 1000; 31 | var poolIdx = Utils.commentPool[Utils.commentIndex]; 32 | while(poolIdx !== undefined && poolIdx.time < secs 33 | && root.commentCount < visual.maxCommentCount){ 34 | if (secs - poolIdx.time < 3){ 35 | var prop = { 36 | "color": Utils.intToColor(poolIdx.color), 37 | "font.pixelSize": poolIdx.fontSize, 38 | "text": poolIdx.text 39 | } 40 | singleComment.createObject(root, prop); 41 | } 42 | poolIdx = Utils.commentPool[++Utils.commentIndex]; 43 | } 44 | } 45 | 46 | Component.onCompleted: get(); 47 | 48 | Component { 49 | id: singleComment; 50 | Text { 51 | id: commentText; 52 | 53 | property int idx: 0; 54 | 55 | x: root.width; 56 | y: idx*18; 57 | textFormat: Text.PlainText; 58 | 59 | NumberAnimation { 60 | id: normalAnimation; 61 | target: commentText; 62 | property: "x"; 63 | from: root.width; 64 | to: -commentText.width; 65 | duration: 3000; 66 | onCompleted: commentText.destroy(); 67 | } 68 | 69 | Component.onCompleted: { 70 | root.commentCount ++; 71 | commentText.idx = Utils.addToScreen(); 72 | normalAnimation.start(); 73 | } 74 | Component.onDestruction: { 75 | root.commentCount --; 76 | Utils.clearFromScreen(commentText.idx); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /qml/js/LetvParser.js: -------------------------------------------------------------------------------- 1 | var LetvParser = new Function(); 2 | LetvParser.prototype = new VideoParser(); 3 | LetvParser.prototype.constructor = LetvParser; 4 | LetvParser.prototype.name = "乐视"; 5 | 6 | LetvParser.prototype.start = function(vid){ 7 | var xhr = new XMLHttpRequest(); 8 | xhr.onreadystatechange = function(){ 9 | if (xhr.readyState == xhr.DONE){ 10 | if (xhr.status == 200){ 11 | try { 12 | var resp = JSON.parse(xhr.responseText); 13 | if (resp.code == 0){ 14 | var vl = resp.data.video_list; 15 | var mainUrl = vl[vl.default_play].main_url; 16 | var result = Qt.atob(mainUrl); 17 | LetvParser.prototype.success(result); 18 | return; 19 | } 20 | } catch (e){ 21 | } 22 | } 23 | LetvParser.prototype.error(); 24 | } 25 | } 26 | var url = "http://api.letvcloud.com/gpc.php?cf=html5&sign=signxxxxx&ver=2.0&format=json&vu=%1&uu=419176ad52".arg(vid); 27 | xhr.open("GET", url); 28 | xhr.send(); 29 | }; 30 | 31 | var Letv2Parser = new Function(); 32 | Letv2Parser.prototype = new VideoParser(); 33 | Letv2Parser.prototype.constructor = Letv2Parser; 34 | Letv2Parser.prototype.name = "乐视"; 35 | 36 | Letv2Parser.prototype.start = function(vid){ 37 | function GenerateKeyRor(value, key) { 38 | var i = 0; 39 | while (i < key) { 40 | value = (0x7fffffff & (value >> 1)) | ((value & 1) << 31); 41 | ++i; 42 | } 43 | return value; 44 | } 45 | function GenerateKey(stime) { 46 | var key = 773625421; 47 | var value = GenerateKeyRor(stime, key % 13); 48 | value = value ^ key; 49 | value = GenerateKeyRor(value, key % 17); 50 | return value; 51 | } 52 | // http://api.letv.com/mms/out/common/geturl?platid=3&splatid=301&callback=vjs_1407252559281&playid=0&vtype=9,13,21&version=2.0&tss=no&vid=20439176&domain=m.letv.com&tkey=-749427743&_r=0 53 | } 54 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/ACPlayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | 3 | Item { 4 | id: root; 5 | 6 | // 视频源地址 7 | property url source; 8 | onSourceChanged: if (videoPlayer) videoPlayer.source = source; 9 | // 弹幕池ID 10 | property string commentId; 11 | // 播放器层接口 12 | property alias videoPlayer: videoPlayerLoader.item; 13 | 14 | signal playStarted; 15 | signal exit; 16 | 17 | function __slotLoadStarted(){ 18 | //开始加载视频,同时加载评论 19 | commentLayerLoader.sourceComponent = commentLayerComp; 20 | } 21 | function __handleExit(){ 22 | if (videoPlayer) videoPlayer.stop(); 23 | root.exit(); 24 | } 25 | 26 | anchors.fill: parent; 27 | 28 | // 播放器层加载器 29 | Loader { 30 | id: videoPlayerLoader; 31 | anchors.fill: parent; 32 | } 33 | 34 | // 延时加载播放器层,防止页面切换时出现卡顿 35 | Timer { 36 | id: playerLoadTimer; 37 | running: true; 38 | interval: visual.animationDurationPrettyLong; 39 | onTriggered: { 40 | stop(); 41 | videoPlayerLoader.sourceComponent = 42 | Qt.createComponent("VideoLayer.qml"); 43 | if (videoPlayerLoader.status === Loader.Ready){ 44 | videoPlayer.loadStarted.connect(__slotLoadStarted); 45 | videoPlayer.playbackStarted.connect(playStarted); 46 | videoPlayer.source = root.source; 47 | } 48 | } 49 | } 50 | 51 | // 评论层加载器 52 | Loader { 53 | id: commentLayerLoader; 54 | anchors.fill: parent; 55 | } 56 | // 评论层组件 57 | Component { 58 | id: commentLayerComp; 59 | CommentLayer { 60 | id: commentLayer; 61 | timePlayed: videoPlayer.timePlayed; 62 | commentId: root.commentId; 63 | } 64 | } 65 | 66 | // 控制器层 67 | ControlLayer { 68 | id: controlLayer; 69 | autoHide: videoPlayer !== null && videoPlayer.isPlaying; 70 | timePlayed: videoPlayer ? videoPlayer.timePlayed : 0; 71 | timeDuration: videoPlayer ? videoPlayer.duration : 0; 72 | isPlaying: videoPlayer ? videoPlayer.isPlaying : false; 73 | backFreezed: videoPlayer ? videoPlayer.freezing : false; 74 | onBackPressed: __handleExit(); 75 | onPausePressed: if(videoPlayer)videoPlayer.pause(); 76 | onPlayPressed: if(videoPlayer)videoPlayer.play(); 77 | onForwardPressed: if(videoPlayer)videoPlayer.forward(); 78 | onBackwardsPressed: if(videoPlayer)videoPlayer.backwards(); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/CommentLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import "../../js/main.js" as Script 3 | import "Comments.js" as Utils 4 | 5 | Item { 6 | id: root; 7 | 8 | property string commentId; 9 | property int timePlayed; 10 | 11 | property int commentCount: 0; 12 | property int secondsPlayed: timePlayed / 1000; 13 | 14 | function get(){ 15 | var opt = { 16 | pool: Utils.commentPool, 17 | cid: commentId 18 | } 19 | function s(){ 20 | console.log("comment loaded"); 21 | root.secondsPlayedChanged.connect(createText); 22 | } 23 | function f(err){ 24 | console.log(err); 25 | } 26 | Script.getSyncComments(opt, s, f); 27 | } 28 | 29 | function createText(){ 30 | if (secondsPlayed === 0) Utils.commentIndex = 0; 31 | var secs = secondsPlayed; 32 | var poolIdx = Utils.commentPool[Utils.commentIndex]; 33 | while(poolIdx !== undefined && poolIdx.time < secs 34 | && root.commentCount < visual.maxCommentCount){ 35 | if (secs - poolIdx.time < 3){ 36 | var prop = { 37 | "color": Utils.intToColor(poolIdx.color), 38 | "font.pixelSize": poolIdx.fontSize, 39 | "text": poolIdx.text 40 | } 41 | singleComment.createObject(root, prop); 42 | } 43 | poolIdx = Utils.commentPool[++Utils.commentIndex]; 44 | } 45 | } 46 | 47 | Component.onCompleted: get(); 48 | 49 | Component { 50 | id: singleComment; 51 | Text { 52 | id: commentText; 53 | 54 | property int idx: 0; 55 | 56 | x: root.width; 57 | y: idx*18; 58 | textFormat: Text.PlainText; 59 | 60 | NumberAnimation { 61 | id: normalAnimation; 62 | target: commentText; 63 | property: "x"; 64 | from: root.width; 65 | to: -commentText.width; 66 | duration: 5000; 67 | onCompleted: commentText.destroy(); 68 | } 69 | 70 | Component.onCompleted: { 71 | root.commentCount ++; 72 | commentText.idx = Utils.addToScreen(); 73 | normalAnimation.start(); 74 | } 75 | Component.onDestruction: { 76 | root.commentCount --; 77 | Utils.clearFromScreen(commentText.idx); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /qml/AcFun/MainPageCom/HomeRow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Column { 5 | id: root; 6 | width: contentCol.width; 7 | property variant videos: model.videos; 8 | ListHeading { 9 | id: listHeading; 10 | ListItemText { 11 | anchors.fill: parent.paddingItem; 12 | role: "Heading"; 13 | text: model.name+" >>"; 14 | } 15 | MouseArea { 16 | anchors.fill: parent; 17 | onClicked: internal.enterClass(model.id); 18 | } 19 | } 20 | ListView { 21 | id: listView; 22 | anchors { left: parent.left; right: parent.right; } 23 | height: 90 + constant.graphicSizeSmall; 24 | model: videos; 25 | orientation: ListView.Horizontal; 26 | delegate: Item { 27 | implicitWidth: 120; 28 | implicitHeight: ListView.view.height; 29 | Image { 30 | id: previewImg; 31 | width: 120; height: 90; 32 | sourceSize: Qt.size(120, 90); 33 | source: model.previewurl; 34 | smooth: true; 35 | onStatusChanged: { 36 | if (status === Image.Error){ 37 | source = "../../gfx/cover-day.png"; 38 | } 39 | } 40 | } 41 | Image { 42 | anchors.centerIn: previewImg; 43 | source: previewImg.status === Image.Ready 44 | ? "" : "../../gfx/photos.svg"; 45 | } 46 | Text { 47 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom; } 48 | height: constant.graphicSizeSmall; 49 | horizontalAlignment: Text.AlignHCenter; 50 | verticalAlignment: Text.AlignVCenter; 51 | font: constant.labelFont; 52 | color: constant.colorLight; 53 | text: model.name; 54 | textFormat: Text.StyledText; 55 | elide: Text.ElideRight; 56 | maximumLineCount: 1; 57 | wrapMode: Text.Wrap; 58 | } 59 | Rectangle { 60 | anchors.fill: parent; 61 | color: "black"; 62 | opacity: mouseArea.pressed ? 0.3 : 0; 63 | } 64 | MouseArea { 65 | id: mouseArea; 66 | anchors.fill: parent; 67 | onClicked: signalCenter.viewDetail(model.acId, model.channelId); 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /AcFun.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | TARGET = AcFun 3 | 4 | VERSION = 2.4.1 5 | DEFINES += VER=\\\"$$VERSION\\\" 6 | 7 | QT += network webkit xml 8 | CONFIG += mobility 9 | MOBILITY += multimedia systeminfo 10 | 11 | RESOURCES += AcFun-res.qrc 12 | 13 | INCLUDEPATH += src 14 | 15 | HEADERS += \ 16 | src/utility.h \ 17 | src/acnetworkaccessmanagerfactory.h \ 18 | src/customwebview.h \ 19 | src/qnetworkrequesthelper.h 20 | 21 | SOURCES += main.cpp \ 22 | src/utility.cpp \ 23 | src/acnetworkaccessmanagerfactory.cpp \ 24 | src/customwebview.cpp \ 25 | src/qnetworkrequesthelper.cpp 26 | 27 | TRANSLATIONS += i18n/AcFun_zh.ts 28 | 29 | folder_symbian3.source = qml/AcFun 30 | folder_symbian3.target = qml 31 | 32 | folder_harmattan.source = qml/harmattan 33 | folder_harmattan.target = qml 34 | 35 | folder_js.source = qml/js 36 | folder_js.target = qml 37 | 38 | folder_gfx.source = qml/gfx 39 | folder_gfx.target = qml 40 | 41 | DEPLOYMENTFOLDERS = folder_js folder_gfx 42 | 43 | simulator { 44 | DEPLOYMENTFOLDERS += folder_symbian3 folder_harmattan 45 | } 46 | 47 | contains(MEEGO_EDITION, harmattan){ 48 | DEFINES += Q_OS_HARMATTAN 49 | CONFIG += qdeclarative-boostable 50 | CONFIG += videosuiteinterface-maemo-meegotouch #video suite 51 | CONFIG += shareuiinterface-maemo-meegotouch share-ui-plugin share-ui-common #share ui 52 | CONFIG += mdatauri #mdatauri 53 | 54 | DEPLOYMENTFOLDERS += folder_harmattan 55 | 56 | splash.files = splash/splash_n9.png 57 | splash.path = /opt/AcFun/bin 58 | 59 | INSTALLS += splash 60 | } 61 | 62 | symbian { 63 | DEPLOYMENTFOLDERS += folder_symbian3 64 | 65 | CONFIG += qt-components 66 | CONFIG += localize_deployment 67 | 68 | TARGET.UID3 = 0x2006622C 69 | TARGET.CAPABILITY *= \ 70 | NetworkServices \ 71 | ReadUserData \ 72 | WriteUserData \ 73 | SwEvent 74 | TARGET.EPOCHEAPSIZE = 0x40000 0x4000000 75 | 76 | LIBS *= -lapparc -lws32 -lapgrfx 77 | 78 | vendorinfo = "%{\"Yeatse\"}" ":\"Yeatse\"" 79 | my_deployment.pkg_prerules += vendorinfo 80 | DEPLOYMENT += my_deployment 81 | 82 | # Symbian have a different syntax 83 | DEFINES -= VER=\\\"$$VERSION\\\" 84 | DEFINES += VER=\"$$VERSION\" 85 | } 86 | 87 | OTHER_FILES += \ 88 | qtc_packaging/debian_harmattan/rules \ 89 | qtc_packaging/debian_harmattan/README \ 90 | qtc_packaging/debian_harmattan/manifest.aegis \ 91 | qtc_packaging/debian_harmattan/copyright \ 92 | qtc_packaging/debian_harmattan/control \ 93 | qtc_packaging/debian_harmattan/compat \ 94 | qtc_packaging/debian_harmattan/changelog 95 | 96 | include(qmlapplicationviewer/qmlapplicationviewer.pri) 97 | qtcAddDeployment() 98 | -------------------------------------------------------------------------------- /qml/harmattan/SearchResultPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | property int orderId: 4; 10 | property string term; 11 | property int nextPage: 1; 12 | property bool hasNext: false; 13 | 14 | function getlist(option){ 15 | loading = true; 16 | var opt = { orderId: orderId, term: term, model: view.model } 17 | if (view.count === 0||nextPage === 1) option = "renew"; 18 | option = option || "renew"; 19 | if (option === "renew"){ 20 | opt.renew = true; 21 | nextPage = 1; 22 | } else { 23 | opt.pageNo = nextPage; 24 | } 25 | function s(obj){ 26 | loading = false; 27 | if (nextPage === obj.nextPage){ 28 | hasNext = false; 29 | } else { 30 | hasNext = true; 31 | nextPage = obj.nextPage; 32 | } 33 | } 34 | function f(err){ 35 | loading = false; 36 | signalCenter.showMessage(err); 37 | } 38 | Script.getSearch(opt, s, f); 39 | } 40 | 41 | tools: ToolBarLayout { 42 | ToolIcon { 43 | platformIconId: "toolbar-back"; 44 | onClicked: pageStack.pop(); 45 | } 46 | ToolIcon { 47 | platformIconId: "toolbar-refresh"; 48 | onClicked: getlist(); 49 | } 50 | } 51 | 52 | ViewHeader { 53 | id: viewheader; 54 | title: "搜索结果"; 55 | } 56 | 57 | ButtonRow { 58 | id: buttonRow; 59 | anchors { left: parent.left; right: parent.right; top: viewheader.bottom; } 60 | enabled: !loading; 61 | Button { 62 | text: "收藏数"; 63 | onClicked: {orderId = 4;getlist();} 64 | } 65 | Button { 66 | text: "点击数"; 67 | onClicked: {orderId = 0;getlist();} 68 | } 69 | Button { 70 | text: "发布时间" 71 | onClicked: {orderId = 2;getlist();} 72 | } 73 | Button { 74 | text: "评论数" 75 | onClicked: {orderId = 3;getlist();} 76 | } 77 | } 78 | 79 | ListView { 80 | id: view; 81 | anchors { left: parent.left; right: parent.right; top: buttonRow.bottom; bottom: parent.bottom; } 82 | clip: true; 83 | model: ListModel {} 84 | delegate: CommonDelegate {} 85 | footer: FooterItem { 86 | visible: hasNext; 87 | enabled: !loading; 88 | onClicked: getlist("next"); 89 | } 90 | } 91 | 92 | ScrollDecorator { flickableItem: view; } 93 | } 94 | -------------------------------------------------------------------------------- /qml/gfx/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/acnetworkaccessmanagerfactory.cpp: -------------------------------------------------------------------------------- 1 | #include "acnetworkaccessmanagerfactory.h" 2 | #include "utility.h" 3 | 4 | ACNetworkAccessManagerFactory::ACNetworkAccessManagerFactory() : 5 | QDeclarativeNetworkAccessManagerFactory() 6 | { 7 | } 8 | 9 | QNetworkAccessManager* ACNetworkAccessManagerFactory::create(QObject *parent) 10 | { 11 | QMutexLocker lock(&mutex); 12 | Q_UNUSED(lock); 13 | QNetworkAccessManager* manager = new ACNetworkAccessManager(parent); 14 | 15 | QNetworkCookieJar* cookieJar = ACNetworkCookieJar::GetInstance(); 16 | manager->setCookieJar(cookieJar); 17 | cookieJar->setParent(0); 18 | 19 | return manager; 20 | } 21 | 22 | ACNetworkAccessManager::ACNetworkAccessManager(QObject *parent) : 23 | QNetworkAccessManager(parent) 24 | { 25 | } 26 | 27 | QNetworkReply *ACNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData) 28 | { 29 | QNetworkRequest req(request); 30 | req.setRawHeader("User-Agent", "Acfun_Video/1.0 (iPod touch; iOS 6.1.3; Scale/2.00)"); 31 | QNetworkReply *reply = QNetworkAccessManager::createRequest(op, req, outgoingData); 32 | return reply; 33 | } 34 | 35 | ACNetworkCookieJar::ACNetworkCookieJar(QObject *parent) : 36 | QNetworkCookieJar(parent) 37 | { 38 | load(); 39 | } 40 | 41 | ACNetworkCookieJar::~ACNetworkCookieJar() 42 | { 43 | save(); 44 | } 45 | 46 | ACNetworkCookieJar* ACNetworkCookieJar::GetInstance() 47 | { 48 | static ACNetworkCookieJar cookieJar; 49 | return &cookieJar; 50 | } 51 | 52 | void ACNetworkCookieJar::clearCookies() 53 | { 54 | QList emptyList; 55 | setAllCookies(emptyList); 56 | } 57 | 58 | QList ACNetworkCookieJar::cookiesForUrl(const QUrl &url) const 59 | { 60 | QMutexLocker lock(&mutex); 61 | Q_UNUSED(lock); 62 | return QNetworkCookieJar::cookiesForUrl(url); 63 | } 64 | 65 | bool ACNetworkCookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) 66 | { 67 | QMutexLocker lock(&mutex); 68 | Q_UNUSED(lock); 69 | return QNetworkCookieJar::setCookiesFromUrl(cookieList, url); 70 | } 71 | 72 | void ACNetworkCookieJar::save() 73 | { 74 | QMutexLocker lock(&mutex); 75 | Q_UNUSED(lock); 76 | QList list = allCookies(); 77 | QByteArray data; 78 | foreach (QNetworkCookie cookie, list) { 79 | if (!cookie.isSessionCookie()){ 80 | data.append(cookie.toRawForm()); 81 | data.append("\n"); 82 | } 83 | } 84 | Utility::Instance()->setValue("Cookies", data); 85 | } 86 | 87 | void ACNetworkCookieJar::load() 88 | { 89 | QMutexLocker lock(&mutex); 90 | Q_UNUSED(lock); 91 | QByteArray data = Utility::Instance()->getValue("Cookies").toByteArray(); 92 | setAllCookies(QNetworkCookie::parseCookies(data)); 93 | } 94 | -------------------------------------------------------------------------------- /qml/harmattan/MainPageCom/HomeRow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "../Component" 4 | 5 | Column { 6 | id: root; 7 | width: contentCol.width; 8 | property variant videos: model.videos; 9 | SectionHeader { 10 | id: listHeading; 11 | title: model.name; 12 | Text { 13 | anchors { 14 | right: parent.right; rightMargin: constant.paddingSmall; 15 | top: parent.top; topMargin: constant.paddingLarge; 16 | } 17 | font: constant.titleFont; 18 | color: constant.colorLight; 19 | text: ">>"; 20 | } 21 | MouseArea { 22 | anchors.fill: parent; 23 | onClicked: internal.enterClass(model.id); 24 | } 25 | } 26 | ListView { 27 | id: listView; 28 | anchors { left: parent.left; right: parent.right; } 29 | height: 120 + constant.graphicSizeSmall; 30 | model: videos; 31 | orientation: ListView.Horizontal; 32 | delegate: Item { 33 | implicitWidth: 160; 34 | implicitHeight: ListView.view.height; 35 | Image { 36 | id: previewImg; 37 | width: 160; height: 120; 38 | sourceSize: Qt.size(160, 120); 39 | source: model.previewurl; 40 | smooth: true; 41 | onStatusChanged: { 42 | if (status === Image.Error){ 43 | source = "../../gfx/cover-day.png"; 44 | } 45 | } 46 | } 47 | Image { 48 | anchors.centerIn: previewImg; 49 | source: previewImg.status === Image.Ready 50 | ? "" : "image://theme/icon-m-toolbar-gallery"; 51 | } 52 | Text { 53 | anchors { left: parent.left; right: parent.right; bottom: parent.bottom; } 54 | height: constant.graphicSizeSmall; 55 | horizontalAlignment: Text.AlignHCenter; 56 | verticalAlignment: Text.AlignVCenter; 57 | font: constant.labelFont; 58 | color: constant.colorLight; 59 | text: model.name; 60 | textFormat: Text.StyledText; 61 | elide: Text.ElideRight; 62 | maximumLineCount: 1; 63 | wrapMode: Text.Wrap; 64 | } 65 | Rectangle { 66 | anchors.fill: parent; 67 | color: "black"; 68 | opacity: mouseArea.pressed ? 0.3 : 0; 69 | } 70 | MouseArea { 71 | id: mouseArea; 72 | anchors.fill: parent; 73 | onClicked: signalCenter.viewDetail(model.acId); 74 | } 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /qml/harmattan/VideoPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "../js/videoSourceLoader.js" as VL 4 | 5 | Page { 6 | id: page; 7 | 8 | property string acId; //ac id; 9 | property string type; //source type; 10 | property string sid; //source id; 11 | property string cid; //comment id; 12 | 13 | orientationLock: PageOrientation.LockLandscape; 14 | onStatusChanged: { 15 | if (status === PageStatus.Activating){ 16 | app.showStatusBar = false; 17 | app.platformStyle.cornersVisible = false; 18 | } 19 | } 20 | 21 | function load(){ 22 | VL.loadSource(type, sid, messageModel); 23 | } 24 | function exit(){ 25 | pageStack.pop(undefined, true); 26 | app.showStatusBar = true; 27 | app.platformStyle.cornersVisible = true; 28 | } 29 | function createPlayer(url){ 30 | playerLoader.sourceComponent = Qt.createComponent("ACPlayer/ACPlayer.qml"); 31 | if (playerLoader.status === Loader.Ready){ 32 | var item = playerLoader.item; 33 | item.source = url; 34 | item.commentId = cid; 35 | item.playStarted.connect(hideMessage); 36 | item.exit.connect(exit); 37 | } else { 38 | console.log("Error: player is not ready"); 39 | } 40 | } 41 | function hideMessage(){ 42 | exitBtn.visible = false; 43 | messageModel.clear(); 44 | } 45 | 46 | Rectangle { 47 | id: bg; 48 | anchors.fill: parent; 49 | color: "black"; 50 | } 51 | 52 | Loader { 53 | id: playerLoader; 54 | anchors.fill: parent; 55 | } 56 | 57 | // return button 58 | Button { 59 | id: exitBtn; 60 | enabled: playerLoader.item === null || 61 | playerLoader.item.videoPlayer === null || 62 | !playerLoader.item.videoPlayer.freezing; 63 | anchors { 64 | right: parent.right; top: parent.top; 65 | margins: constant.paddingSmall; 66 | } 67 | platformStyle: ButtonStyle { 68 | inverted: true; 69 | buttonWidth: buttonHeight; 70 | } 71 | iconSource: "image://theme/icon-m-toolbar-close-white"; 72 | onClicked: exit(); 73 | } 74 | 75 | // messages 76 | Column { 77 | id: contentCol; 78 | anchors { 79 | left: parent.left; bottom: parent.bottom; 80 | margins: constant.paddingSmall; 81 | } 82 | spacing: constant.paddingSmall; 83 | Repeater { 84 | model: ListModel { id: messageModel; } 85 | Text { 86 | font: constant.labelFont; 87 | color: "white"; 88 | text: modelData; 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /qml/harmattan/RankingPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | tools: ToolBarLayout { 10 | ToolIcon { 11 | platformIconId: "toolbar-back"; 12 | onClicked: pageStack.pop(); 13 | } 14 | ToolIcon { 15 | platformIconId: "toolbar-refresh"; 16 | onClicked: internal.getlist(); 17 | } 18 | } 19 | 20 | Component.onCompleted: internal.getlist(); 21 | 22 | QtObject { 23 | id: internal; 24 | 25 | property int pageNumber: 1; 26 | property int totalNumber: 0; 27 | property int pageSize: 20; 28 | 29 | property int classId: 1024; 30 | property bool isoriginal: false; 31 | 32 | function getlist(option){ 33 | loading = true; 34 | var opt = { 35 | model: view.model, 36 | "class": classId, 37 | isoriginal: isoriginal 38 | }; 39 | if (view.count === 0) option = "renew"; 40 | option = option || "renew"; 41 | if (option === "renew"){ 42 | opt.renew = true; 43 | } else { 44 | opt.cursor = pageNumber * pageSize; 45 | } 46 | function s(obj){ 47 | loading = false; 48 | pageNumber = obj.pageNo; 49 | totalNumber = obj.totalCount; 50 | pageSize = obj.pageSize; 51 | } 52 | function f(err){ loading = false; signalCenter.showMessage(err); } 53 | Script.getClass(opt, s, f); 54 | } 55 | } 56 | 57 | ViewHeader { 58 | id: viewHeader; 59 | title: "排名"; 60 | } 61 | 62 | ButtonRow { 63 | id: btnRow; 64 | anchors { top: viewHeader.bottom; left: parent.left; right: parent.right; } 65 | Button { 66 | text: "综合"; 67 | onClicked: { 68 | internal.isoriginal = false; 69 | internal.getlist(); 70 | } 71 | } 72 | Button { 73 | text: "原创"; 74 | onClicked: { 75 | internal.isoriginal = true; 76 | internal.getlist(); 77 | } 78 | } 79 | } 80 | 81 | ListView { 82 | id: view; 83 | anchors { 84 | left: parent.left; right: parent.right; 85 | top: btnRow.bottom; bottom: parent.bottom; 86 | } 87 | clip: true; 88 | model: ListModel {} 89 | delegate: CommonDelegate {} 90 | footer: FooterItem { 91 | visible: internal.pageSize * internal.pageNumber < internal.totalNumber; 92 | enabled: !loading; 93 | onClicked: internal.getlist("next"); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /qml/gfx/tb_close_stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /qml/harmattan/MainPageCom/HeaderView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | property alias model: headerView.model; 8 | property bool loading: false; 9 | property bool error: false; 10 | 11 | signal refresh; 12 | 13 | implicitWidth: parent.width; 14 | implicitHeight: Math.floor(width/64*25); 15 | 16 | clip: true; 17 | 18 | PathView { 19 | id: headerView; 20 | anchors.fill: parent; 21 | model: ListModel {} 22 | preferredHighlightBegin: 0.5; 23 | preferredHighlightEnd: 0.5; 24 | path: Path { 25 | startX: -headerView.width*headerView.count/2+headerView.width/2; 26 | startY: headerView.height/2; 27 | PathLine { 28 | x: headerView.width*headerView.count/2+headerView.width/2; 29 | y: headerView.height/2; 30 | } 31 | } 32 | delegate: Item { 33 | implicitWidth: PathView.view.width; 34 | implicitHeight: PathView.view.height; 35 | Image { 36 | id: previewImg; 37 | anchors.fill: parent; 38 | smooth: true; 39 | source: model.previewurl; 40 | } 41 | Image { 42 | anchors.centerIn: parent; 43 | source: previewImg.status === Image.Ready ? "" : "image://theme/icon-m-toolbar-gallery"; 44 | } 45 | Rectangle { 46 | anchors.fill: parent; 47 | color: "black"; 48 | opacity: mouseArea.pressed ? 0.3 : 0; 49 | } 50 | MouseArea { 51 | id: mouseArea; 52 | anchors.fill: parent; 53 | onClicked: signalCenter.viewDetail(model.jumpurl) 54 | } 55 | } 56 | Timer { 57 | running: headerView.visible && headerView.count > 0 && !headerView.moving; 58 | interval: 3000; 59 | repeat: true; 60 | onTriggered: headerView.incrementCurrentIndex(); 61 | } 62 | } 63 | 64 | Row { 65 | anchors { right: parent.right; bottom: parent.bottom; margins: constant.paddingMedium; } 66 | spacing: constant.paddingSmall; 67 | Repeater { 68 | model: headerView.count; 69 | Rectangle { 70 | width: constant.paddingMedium; 71 | height: constant.paddingMedium; 72 | border { width: 1; color: "white"; } 73 | radius: width /2; 74 | color: index === headerView.currentIndex ? "red" : "transparent"; 75 | } 76 | } 77 | } 78 | 79 | Button { 80 | visible: root.error; 81 | anchors.centerIn: parent; 82 | platformStyle: ButtonStyle { buttonWidth: buttonHeight; } 83 | iconSource: "image://theme/icon-m-toolbar-refresh"; 84 | onClicked: root.refresh(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /qml/AcFun/MainPageCom/HeaderView.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Item { 5 | id: root; 6 | 7 | property alias model: headerView.model; 8 | property bool loading: false; 9 | property bool error: false; 10 | 11 | signal refresh; 12 | 13 | implicitWidth: parent.width; 14 | implicitHeight: Math.floor(width/64*25); 15 | 16 | clip: true; 17 | 18 | PathView { 19 | id: headerView; 20 | anchors.fill: parent; 21 | model: ListModel {} 22 | preferredHighlightBegin: 0.5; 23 | preferredHighlightEnd: 0.5; 24 | path: Path { 25 | startX: -headerView.width*headerView.count/2+headerView.width/2; 26 | startY: headerView.height/2; 27 | PathLine { 28 | x: headerView.width*headerView.count/2+headerView.width/2; 29 | y: headerView.height/2; 30 | } 31 | } 32 | delegate: Item { 33 | implicitWidth: PathView.view.width; 34 | implicitHeight: PathView.view.height; 35 | Image { 36 | id: previewImg; 37 | anchors.fill: parent; 38 | smooth: true; 39 | source: model.previewurl; 40 | } 41 | Image { 42 | anchors.centerIn: parent; 43 | source: previewImg.status === Image.Ready 44 | ? "" : "../../gfx/photos.svg"; 45 | } 46 | Rectangle { 47 | anchors.fill: parent; 48 | color: "black"; 49 | opacity: mouseArea.pressed ? 0.3 : 0; 50 | } 51 | MouseArea { 52 | id: mouseArea; 53 | anchors.fill: parent; 54 | onClicked: signalCenter.viewDetail(model.jumpurl) 55 | } 56 | } 57 | Timer { 58 | running: headerView.visible && headerView.count > 0 && !headerView.moving; 59 | interval: 3000; 60 | repeat: true; 61 | onTriggered: headerView.incrementCurrentIndex(); 62 | } 63 | } 64 | 65 | Row { 66 | anchors { right: parent.right; bottom: parent.bottom; margins: constant.paddingMedium; } 67 | spacing: constant.paddingSmall; 68 | Repeater { 69 | model: headerView.count; 70 | Rectangle { 71 | width: constant.paddingMedium; 72 | height: constant.paddingMedium; 73 | border { width: 1; color: "white"; } 74 | radius: width /2; 75 | color: index === headerView.currentIndex ? "red" : "transparent"; 76 | } 77 | } 78 | } 79 | 80 | Button { 81 | id: refreshButton; 82 | visible: root.error; 83 | anchors.centerIn: parent; 84 | width: height; 85 | iconSource: privateStyle.toolBarIconPath("toolbar-refresh"); 86 | onClicked: root.refresh(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "qmlapplicationviewer.h" 5 | #include "src/utility.h" 6 | #include "src/customwebview.h" 7 | #include "src/acnetworkaccessmanagerfactory.h" 8 | #include "src/qnetworkrequesthelper.h" 9 | #ifdef Q_WS_SIMULATOR 10 | #include 11 | #endif 12 | 13 | Q_DECL_EXPORT int main(int argc, char *argv[]) 14 | { 15 | // Symbian specific 16 | #ifdef Q_OS_SYMBIAN 17 | QApplication::setAttribute(Qt::AA_CaptureMultimediaKeys); 18 | #endif 19 | 20 | QScopedPointer app(createApplication(argc, argv)); 21 | 22 | // Splash screen 23 | #if defined(Q_WS_SIMULATOR)||defined(Q_OS_SYMBIAN) 24 | QPixmap p(":/splash/splash_640.png"); 25 | QSplashScreen* splash = new QSplashScreen(p); 26 | splash->show(); 27 | splash->raise(); 28 | #endif 29 | 30 | app->setApplicationName("AcFun"); 31 | app->setOrganizationName("Yeatse"); 32 | app->setApplicationVersion(VER); 33 | 34 | // Install translator for qt 35 | QString locale = QLocale::system().name(); 36 | QTranslator qtTranslator; 37 | if (qtTranslator.load("qt_"+locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) 38 | app->installTranslator(&qtTranslator); 39 | QTranslator translator; 40 | if (translator.load(app->applicationName()+"_"+locale, ":/i18n/")) 41 | app->installTranslator(&translator); 42 | 43 | // For fiddler network debugging 44 | #ifdef Q_WS_SIMULATOR 45 | QNetworkProxy proxy; 46 | proxy.setType(QNetworkProxy::HttpProxy); 47 | proxy.setHostName("localhost"); 48 | proxy.setPort(8888); 49 | QNetworkProxy::setApplicationProxy(proxy); 50 | #endif 51 | 52 | // Custom web view and css settings 53 | qmlRegisterType(); 54 | qmlRegisterType("CustomWebKit", 1, 0, "WebView"); 55 | QWebSettings::globalSettings()->setUserStyleSheetUrl(QUrl::fromLocalFile("qml/js/theme.css")); 56 | 57 | qmlRegisterType("com.yeatse.acfun", 1, 0, "NetworkHelper"); 58 | 59 | QmlApplicationViewer viewer; 60 | 61 | viewer.setAttribute(Qt::WA_NoSystemBackground); 62 | viewer.setProperty("orientationMethod", 1); 63 | viewer.setOrientation(QmlApplicationViewer::ScreenOrientationLockPortrait); 64 | 65 | ACNetworkAccessManagerFactory factory; 66 | viewer.engine()->setNetworkAccessManagerFactory(&factory); 67 | viewer.rootContext()->setContextProperty("utility", Utility::Instance()); 68 | #ifdef Q_OS_SYMBIAN 69 | viewer.setMainQmlFile(QLatin1String("qml/AcFun/main.qml")); 70 | #elif defined(Q_OS_HARMATTAN) 71 | viewer.setMainQmlFile(QLatin1String("qml/harmattan/main.qml")); 72 | #else 73 | viewer.setMainQmlFile(QLatin1String("qml/AcFun/main.qml")); 74 | #endif 75 | viewer.showExpanded(); 76 | 77 | #if defined(Q_WS_SIMULATOR) || defined(Q_OS_SYMBIAN) 78 | splash->deleteLater(); 79 | #endif 80 | 81 | return app->exec(); 82 | } 83 | -------------------------------------------------------------------------------- /qml/harmattan/Component/PullToActivate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | 4 | Item { 5 | id: root 6 | 7 | property Flickable myView 8 | 9 | property int visualY 10 | 11 | property bool reloadTriggered 12 | 13 | property int indicatorStart: 25 14 | property int refreshStart: 120 15 | 16 | property string pullDownMessage: isHeader ? qsTr("Pull Down To Activate") : qsTr("Pull Up To Activate"); 17 | property string releaseRefreshMessage: qsTr("Release To Activate"); 18 | property string disabledMessage: qsTr("Now loading"); 19 | 20 | property bool isHeader: true; 21 | 22 | signal refresh; 23 | 24 | width: parent ? parent.width : app.inPortrait ? screen.displayHeight : screen.displayWidth; 25 | height: 0 26 | 27 | Connections { 28 | target: myView 29 | onContentYChanged: { 30 | if (isHeader){ 31 | if (myView.atYBeginning){ 32 | var y = root.mapToItem(myView, 0, 0).y 33 | if ( y < refreshStart + 20 ) 34 | visualY = y 35 | } 36 | } else { 37 | if (myView.atYEnd){ 38 | var y = root.mapToItem(myView, 0, 0).y 39 | if ( myView.height - y < refreshStart + 20 ) 40 | visualY = myView.height - y 41 | } 42 | } 43 | } 44 | } 45 | 46 | Row { 47 | anchors { 48 | bottom: isHeader ? parent.top : undefined; top: isHeader ? undefined : parent.bottom 49 | horizontalCenter: parent.horizontalCenter 50 | bottomMargin: isHeader ? constant.paddingLarge : 0 51 | topMargin: isHeader ? 0 : constant.paddingLarge 52 | } 53 | Image { 54 | source: theme.inverted 55 | ? "../../gfx/pull_down.svg" : "../../gfx/pull_down_inverse.svg" 56 | opacity: visualY < indicatorStart ? 0 : 1 57 | Behavior on opacity { NumberAnimation { duration: 100 } } 58 | rotation: { 59 | var newAngle = visualY 60 | if (newAngle > refreshStart && !myView.flicking){ 61 | root.reloadTriggered = true 62 | return isHeader ? -180 : 0 63 | } else { 64 | newAngle = newAngle > refreshStart ? 180 : 0 65 | return isHeader ? -newAngle : newAngle - 180 66 | } 67 | } 68 | Behavior on rotation { NumberAnimation { duration: 150 } } 69 | onOpacityChanged: { 70 | if (opacity == 0 && root.reloadTriggered) { 71 | root.reloadTriggered = false 72 | if (root.enabled){ 73 | root.refresh(); 74 | } 75 | } 76 | } 77 | } 78 | Label { 79 | text: root.enabled ? reloadTriggered ? releaseRefreshMessage : pullDownMessage : disabledMessage; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /qml/AcFun/SearchResultPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | property int orderId: 4; 10 | property string term; 11 | property int nextPage: 1; 12 | property bool hasNext: false; 13 | 14 | function getlist(option){ 15 | loading = true; 16 | var opt = { orderId: orderId, term: term, model: view.model } 17 | if (view.count === 0||nextPage === 1) option = "renew"; 18 | option = option || "renew"; 19 | if (option === "renew"){ 20 | opt.renew = true; 21 | nextPage = 1; 22 | } else { 23 | opt.pageNo = nextPage; 24 | } 25 | function s(obj){ 26 | loading = false; 27 | if (nextPage === obj.nextPage){ 28 | hasNext = false; 29 | } else { 30 | hasNext = true; 31 | nextPage = obj.nextPage; 32 | } 33 | } 34 | function f(err){ 35 | loading = false; 36 | signalCenter.showMessage(err); 37 | } 38 | Script.getSearch(opt, s, f); 39 | } 40 | 41 | title: viewheader.title; 42 | 43 | tools: ToolBarLayout { 44 | ToolButton { 45 | iconSource: "toolbar-back"; 46 | onClicked: pageStack.pop(); 47 | } 48 | ToolButton { 49 | iconSource: "toolbar-refresh"; 50 | onClicked: getlist(); 51 | } 52 | } 53 | 54 | ViewHeader { 55 | id: viewheader; 56 | title: "搜索结果"; 57 | } 58 | 59 | ButtonRow { 60 | id: buttonRow; 61 | anchors { left: parent.left; right: parent.right; top: viewheader.bottom; } 62 | enabled: !loading; 63 | TabButton { 64 | height: privateStyle.tabBarHeightLandscape 65 | text: "收藏数"; 66 | onClicked: {orderId = 4;getlist();} 67 | } 68 | TabButton { 69 | height: privateStyle.tabBarHeightLandscape 70 | text: "点击数"; 71 | onClicked: {orderId = 0;getlist();} 72 | } 73 | TabButton { 74 | height: privateStyle.tabBarHeightLandscape 75 | text: "发布时间" 76 | onClicked: {orderId = 2;getlist();} 77 | } 78 | TabButton { 79 | height: privateStyle.tabBarHeightLandscape 80 | text: "评论数" 81 | onClicked: {orderId = 3;getlist();} 82 | } 83 | } 84 | 85 | ListView { 86 | id: view; 87 | anchors { left: parent.left; right: parent.right; top: buttonRow.bottom; bottom: parent.bottom; } 88 | clip: true; 89 | model: ListModel {} 90 | delegate: CommonDelegate {} 91 | footer: FooterItem { 92 | visible: hasNext; 93 | enabled: !loading; 94 | onClicked: getlist("next"); 95 | } 96 | } 97 | 98 | ScrollDecorator { flickableItem: view; } 99 | } 100 | -------------------------------------------------------------------------------- /qml/AcFun/Component/PullToActivate.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | 4 | Item { 5 | id: root 6 | 7 | property Flickable myView 8 | 9 | property int visualY 10 | 11 | property bool reloadTriggered 12 | 13 | property int indicatorStart: 25 14 | property int refreshStart: 120 15 | 16 | property string pullDownMessage: isHeader ? qsTr("Pull Down To Activate") : qsTr("Pull Up To Activate"); 17 | property string releaseRefreshMessage: qsTr("Release To Activate"); 18 | property string disabledMessage: qsTr("Now loading"); 19 | 20 | property bool platformInverted: false; 21 | property bool isHeader: true; 22 | 23 | signal refresh; 24 | 25 | width: parent ? parent.width : screen.width 26 | height: 0 27 | 28 | Connections { 29 | target: myView 30 | onContentYChanged: { 31 | if (isHeader){ 32 | if (myView.atYBeginning){ 33 | var y = root.mapToItem(myView, 0, 0).y 34 | if ( y < refreshStart + 20 ) 35 | visualY = y 36 | } 37 | } else { 38 | if (myView.atYEnd){ 39 | var y = root.mapToItem(myView, 0, 0).y 40 | if ( myView.height - y < refreshStart + 20 ) 41 | visualY = myView.height - y 42 | } 43 | } 44 | } 45 | } 46 | 47 | Row { 48 | anchors { 49 | bottom: isHeader ? parent.top : undefined; top: isHeader ? undefined : parent.bottom 50 | horizontalCenter: parent.horizontalCenter 51 | bottomMargin: isHeader ? platformStyle.paddingLarge : 0 52 | topMargin: isHeader ? 0 : platformStyle.paddingLarge 53 | } 54 | Image { 55 | source: root.platformInverted ? "../../gfx/pull_down_inverse.svg" 56 | : "../../gfx/pull_down.svg" 57 | opacity: visualY < indicatorStart ? 0 : 1 58 | Behavior on opacity { NumberAnimation { duration: 100 } } 59 | rotation: { 60 | var newAngle = visualY 61 | if (newAngle > refreshStart && !myView.flicking){ 62 | root.reloadTriggered = true 63 | return isHeader ? -180 : 0 64 | } else { 65 | newAngle = newAngle > refreshStart ? 180 : 0 66 | return isHeader ? -newAngle : newAngle - 180 67 | } 68 | } 69 | Behavior on rotation { NumberAnimation { duration: 150 } } 70 | onOpacityChanged: { 71 | if (opacity == 0 && root.reloadTriggered) { 72 | root.reloadTriggered = false 73 | if (root.enabled){ 74 | root.refresh(); 75 | } 76 | } 77 | } 78 | } 79 | Label { 80 | platformInverted: root.platformInverted 81 | text: root.enabled ? reloadTriggered ? releaseRefreshMessage : pullDownMessage : disabledMessage; 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /qml/AcFun/RankingPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | title: viewHeader.title; 10 | 11 | tools: ToolBarLayout { 12 | ToolButton { 13 | iconSource: "toolbar-back"; 14 | onClicked: pageStack.pop(); 15 | } 16 | ToolButton { 17 | iconSource: "toolbar-refresh"; 18 | onClicked: internal.getlist(); 19 | } 20 | } 21 | 22 | Component.onCompleted: internal.getlist(); 23 | 24 | QtObject { 25 | id: internal; 26 | 27 | property int pageNumber: 1; 28 | property int totalNumber: 0; 29 | property int pageSize: 20; 30 | 31 | property int classId: 1024; 32 | property bool isoriginal: false; 33 | 34 | function getlist(option){ 35 | loading = true; 36 | var opt = { 37 | model: view.model, 38 | "class": classId, 39 | isoriginal: isoriginal 40 | }; 41 | if (view.count === 0) option = "renew"; 42 | option = option || "renew"; 43 | if (option === "renew"){ 44 | opt.renew = true; 45 | } else { 46 | opt.cursor = pageNumber * pageSize; 47 | } 48 | function s(obj){ 49 | loading = false; 50 | pageNumber = obj.pageNo; 51 | totalNumber = obj.totalCount; 52 | pageSize = obj.pageSize; 53 | } 54 | function f(err){ loading = false; signalCenter.showMessage(err); } 55 | Script.getClass(opt, s, f); 56 | } 57 | } 58 | 59 | ViewHeader { 60 | id: viewHeader; 61 | title: "排名"; 62 | } 63 | 64 | ButtonRow { 65 | id: btnRow; 66 | anchors { top: viewHeader.bottom; left: parent.left; right: parent.right; } 67 | TabButton { 68 | height: privateStyle.tabBarHeightLandscape; 69 | text: "综合"; 70 | onClicked: { 71 | internal.isoriginal = false; 72 | internal.getlist(); 73 | } 74 | } 75 | TabButton { 76 | height: privateStyle.tabBarHeightLandscape; 77 | text: "原创"; 78 | onClicked: { 79 | internal.isoriginal = true; 80 | internal.getlist(); 81 | } 82 | } 83 | } 84 | 85 | ListView { 86 | id: view; 87 | anchors { 88 | left: parent.left; right: parent.right; 89 | top: btnRow.bottom; bottom: parent.bottom; 90 | } 91 | clip: true; 92 | model: ListModel {} 93 | delegate: CommonDelegate {} 94 | footer: FooterItem { 95 | visible: internal.pageSize * internal.pageNumber < internal.totalNumber; 96 | enabled: !loading; 97 | onClicked: internal.getlist("next"); 98 | } 99 | } 100 | 101 | ScrollDecorator { flickableItem: view; } 102 | } 103 | -------------------------------------------------------------------------------- /qml/js/acapi.js: -------------------------------------------------------------------------------- 1 | .pragma library 2 | 3 | var AcApi = { 4 | clientId: "hf2QkYjrqcT3ndr9", 5 | authorize: "https://ssl.acfun.tv/oauth2/authorize.aspx", 6 | redirectUri: "https://ssl.acfun.tv/authSuccess.aspx", 7 | 8 | videocategories: "http://api.acfun.tv:1069/videocategories", 9 | home_thumbnails: "http://api.acfun.tv:1069/home/thumbnails", 10 | home_categories: "http://api.acfun.tv:1069/home/categories", 11 | videos: "http://api.acfun.tv:1069/videos", 12 | series: "http://api.acfun.tv:1069/series", 13 | videos_playbill: "http://api.acfun.tv:1069/videos/playbill", 14 | hotkeys: "http://api.acfun.tv:1069/hotkeys", 15 | videos_search: "http://api.acfun.tv:1069/videos/search", 16 | danmaku: "http://danmaku1.acfun.tv", 17 | users: "http://api.acfun.tv:1069/users", 18 | 19 | video_comment: "http://static.comment.acfun.tv" 20 | } 21 | 22 | var WebRequest = function (method, url){ 23 | this.method = method; 24 | this.url = url; 25 | this.parameters = new Object(); 26 | this.encodedParams = function(){ 27 | var res = []; 28 | for (var i in this.parameters){ 29 | res.push(i+"="+encodeURIComponent(this.parameters[i])); 30 | } 31 | return res.join("&"); 32 | } 33 | } 34 | 35 | WebRequest.prototype.setParameters = function(param){ 36 | for (var i in param) this.parameters[i] = param[i]; 37 | } 38 | 39 | WebRequest.prototype.sendRequest = function(onSuccess, onFailed){ 40 | console.log("request==========\n", this.url); 41 | var xhr = new XMLHttpRequest(); 42 | xhr.onreadystatechange = function(){ 43 | if (xhr.readyState === xhr.DONE){ 44 | if (xhr.status === 200 || xhr.status === 201){ 45 | var res; 46 | try { 47 | res = JSON.parse(xhr.responseText); 48 | } catch(e){ 49 | res = xhr.responseText; 50 | } 51 | try { 52 | onSuccess(res); 53 | } catch(e){ 54 | onFailed(JSON.stringify(e)); 55 | } 56 | } else { 57 | onFailed(xhr.status); 58 | } 59 | } 60 | } 61 | var p = this.encodedParams(), m = this.method; 62 | if (m === "GET" && p.length > 0){ 63 | xhr.open("GET", this.url+"?"+p); 64 | } else { 65 | xhr.open(m, this.url); 66 | } 67 | 68 | if (m === "POST"){ 69 | xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 70 | xhr.setRequestHeader("Content-Length", p.length); 71 | xhr.send(p); 72 | } else if (m === "GET"){ 73 | xhr.send(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/qnetworkrequesthelper.cpp: -------------------------------------------------------------------------------- 1 | #include "qnetworkrequesthelper.h" 2 | #include "utility.h" 3 | #include "zlib.h" 4 | 5 | QNetworkRequestHelper::QNetworkRequestHelper(QObject *parent) : 6 | QObject(parent), 7 | nam(0) 8 | { 9 | } 10 | 11 | void QNetworkRequestHelper::classBegin() 12 | { 13 | QDeclarativeEngine* engine = qmlEngine(this); 14 | if (QDeclarativeNetworkAccessManagerFactory* factory = engine->networkAccessManagerFactory()){ 15 | nam = factory->create(this); 16 | } else { 17 | nam = engine->networkAccessManager(); 18 | } 19 | connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(slotRequestFinished(QNetworkReply*))); 20 | } 21 | 22 | void QNetworkRequestHelper::componentComplete() 23 | { 24 | } 25 | 26 | void QNetworkRequestHelper::createDeleteRequest(QUrl url) 27 | { 28 | qDebug() << "delete request===========\n" << url; 29 | QNetworkRequest req(url); 30 | QByteArray auth = Utility::Instance()->getValue("accessToken").toByteArray(); 31 | auth.prepend("Bearer "); 32 | req.setRawHeader("Authorization", auth); 33 | req.setHeader(QNetworkRequest::ContentLengthHeader, 0); 34 | 35 | nam->deleteResource(req); 36 | } 37 | 38 | void QNetworkRequestHelper::createDeflatedRequest(QUrl url) 39 | { 40 | qDebug() << "deflate request============\n" << url; 41 | QNetworkRequest req(url); 42 | req.setRawHeader("Accept-Encoding", "gzip, deflate"); 43 | nam->get(req); 44 | } 45 | 46 | void QNetworkRequestHelper::slotRequestFinished(QNetworkReply *reply) 47 | { 48 | reply->deleteLater(); 49 | if (reply->error() != QNetworkReply::NoError){ 50 | emit requestFailed(reply->url()); 51 | } else { 52 | QByteArray data = reply->readAll(); 53 | if (reply->rawHeader("Content-Encoding") == "gzip"){ 54 | data = this->gUncompress(data); 55 | } 56 | emit requestFinished(reply->url(), QString(data)); 57 | } 58 | } 59 | 60 | QByteArray QNetworkRequestHelper::gUncompress(const QByteArray &data) 61 | { 62 | if (data.size() <= 4){ 63 | qWarning("gUncompress: Input data is truncated"); 64 | return data; 65 | } 66 | QByteArray result; 67 | 68 | int ret; 69 | z_stream strm; 70 | static const int CHUNK_SIZE = 1024; 71 | char out[CHUNK_SIZE]; 72 | 73 | strm.zalloc = Z_NULL; 74 | strm.zfree = Z_NULL; 75 | strm.opaque = Z_NULL; 76 | strm.avail_in = data.size(); 77 | strm.next_in = (Bytef*)(data.data()); 78 | 79 | ret = inflateInit2(&strm, 15+32); 80 | if (ret != Z_OK) 81 | return data; 82 | 83 | do { 84 | strm.avail_out = CHUNK_SIZE; 85 | strm.next_out = (Bytef*)(out); 86 | 87 | ret = inflate(&strm, Z_NO_FLUSH); 88 | Q_ASSERT(ret != Z_STREAM_ERROR); 89 | 90 | switch (ret){ 91 | case Z_NEED_DICT: 92 | ret = Z_DATA_ERROR; 93 | case Z_DATA_ERROR: 94 | case Z_MEM_ERROR: 95 | (void)inflateEnd(&strm); 96 | return data; 97 | } 98 | result.append(out, CHUNK_SIZE - strm.avail_out); 99 | } while (strm.avail_out == 0); 100 | 101 | inflateEnd(&strm); 102 | return result; 103 | } 104 | -------------------------------------------------------------------------------- /qml/gfx/pull_down_inverse.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 24 | image/svg+xml 25 | 27 | 28 | 29 | 30 | 31 | 51 | 56 | 61 | 69 | 71 | 79 | 83 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /qml/harmattan/Component/FastScroll.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2012 Dickson Leong 3 | This file is part of Tweetian. 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | */ 18 | 19 | var sectionData = []; 20 | var _sections = []; 21 | 22 | function initialize(list) { 23 | initSectionData(list); 24 | } 25 | 26 | function initSectionData(list) { 27 | if (!list || !list.model) return; 28 | sectionData = []; 29 | _sections = []; 30 | var current = "", 31 | prop = list.section.property, 32 | item; 33 | 34 | if (list.section.criteria == ViewSection.FullString) { 35 | for (var i = 0, count = list.model.count; i < count; i++) { 36 | item = list.model.get(i); 37 | if (item[prop] !== current) { 38 | current = item[prop]; 39 | _sections.push(current); 40 | sectionData.push({ index: i, header: current }); 41 | } 42 | } 43 | } else if (list.section.criteria == ViewSection.FirstCharacter) { 44 | for (var i = 0, count = list.model.count; i < count; i++) { 45 | item = list.model.get(i) 46 | if (item[prop].substring(0, 1) !== current) { 47 | current = item[prop].substring(0, 1); 48 | _sections.push(current); 49 | sectionData.push({ index: i, header: current }); 50 | } 51 | } 52 | } 53 | } 54 | 55 | function getSectionPositionString(name) { 56 | var val = _sections.indexOf(name); 57 | return val === 0 ? "first" : 58 | val === _sections.length - 1 ? "last" : false; 59 | } 60 | 61 | function getAt(pos) { 62 | return _sections[pos] ? _sections[pos] : ""; 63 | } 64 | 65 | function getRelativeSections(current) { 66 | var val = _sections.indexOf(current), 67 | sect = [], 68 | sl = _sections.length; 69 | 70 | val = val < 1 ? 1 : val >= sl-1 ? sl-2 : val; 71 | sect = [getAt(val - 1), getAt(val), getAt(val + 1)]; 72 | 73 | return sect; 74 | } 75 | 76 | function getClosestSection(pos, down) { 77 | var tmp = (_sections.length) * pos; 78 | var val = Math.ceil(tmp) // TODO: better algorithm 79 | val = val < 2 ? 1 : val; 80 | return _sections[val-1]; 81 | } 82 | 83 | function getNextSection(current) { 84 | var val = _sections.indexOf(current); 85 | return (val > -1 ? _sections[(val < _sections.length - 1 ? val + 1 : val)] : _sections[0]) || ""; 86 | } 87 | 88 | function getPreviousSection(current) { 89 | var val = _sections.indexOf(current); 90 | return (val > -1 ? _sections[(val > 0 ? val - 1 : val)] : _sections[0]) || ""; 91 | } 92 | 93 | function getIndexFor(sectionName) { 94 | var val = sectionData[_sections.indexOf(sectionName)].index; 95 | return val === 0 || val > 0 ? val : -1; 96 | } 97 | -------------------------------------------------------------------------------- /qml/gfx/pull_down.svg: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 22 | 24 | image/svg+xml 25 | 27 | 28 | 29 | 30 | 31 | 33 | 53 | 58 | 63 | 68 | 76 | 77 | -------------------------------------------------------------------------------- /qml/harmattan/ClassPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | property int cid; 10 | property string cname; 11 | property variant subclass; 12 | onSubclassChanged: internal.loadModel(); 13 | 14 | tools: ToolBarLayout { 15 | ToolIcon { 16 | platformIconId: "toolbar-back"; 17 | onClicked: pageStack.pop(); 18 | } 19 | ToolIcon { 20 | platformIconId: "toolbar-refresh"; 21 | onClicked: getlist(); 22 | } 23 | } 24 | 25 | function getlist(){ internal.getlist(); } 26 | 27 | QtObject { 28 | id: internal; 29 | 30 | property int pageNumber: 1; 31 | property int totalNumber: 0; 32 | property int pageSize: 20; 33 | 34 | property int classId; 35 | property string className; 36 | 37 | function setClass(){ 38 | if (subclass){ 39 | var item = subclass[subclassSelector.selectedIndex]; 40 | if (item){ 41 | classId = item.id; 42 | className = item.name; 43 | } 44 | } 45 | } 46 | 47 | function loadModel(){ 48 | var m = subclassSelector.model; 49 | m.clear(); 50 | subclass.forEach(function(value){ 51 | m.append({name: value.name}); 52 | }) 53 | subclassSelector.selectedIndex = 0; 54 | } 55 | 56 | function getlist(option){ 57 | loading = true; 58 | var opt = { model: view.model, "class": classId }; 59 | if (view.count === 0) option = "renew"; 60 | option = option || "renew"; 61 | if (option === "renew"){ 62 | opt.renew = true; 63 | } else { 64 | opt.cursor = pageNumber * pageSize; 65 | } 66 | function s(obj){ 67 | loading = false; 68 | pageNumber = obj.pageNo; 69 | totalNumber = obj.totalCount; 70 | pageSize = obj.pageSize; 71 | } 72 | function f(err){ loading = false; signalCenter.showMessage(err); } 73 | Script.getClass(opt, s, f); 74 | } 75 | } 76 | 77 | SelectionDialog { 78 | id: subclassSelector; 79 | titleText: cname; 80 | model: ListModel {} 81 | onSelectedIndexChanged: internal.setClass(); 82 | onAccepted: internal.getlist(); 83 | } 84 | 85 | ViewHeader { 86 | id: viewheader; 87 | title: page.cname + "-" + internal.className; 88 | ToolIcon { 89 | anchors { 90 | right: parent.right; verticalCenter: parent.verticalCenter; 91 | } 92 | platformIconId: "toolbar-view-menu"; 93 | onClicked: subclassSelector.open(); 94 | } 95 | } 96 | 97 | ListView { 98 | id: view; 99 | anchors { fill: parent; topMargin: viewheader.height; } 100 | model: ListModel {} 101 | delegate: CommonDelegate {} 102 | footer: FooterItem { 103 | visible: internal.pageSize * internal.pageNumber < internal.totalNumber; 104 | enabled: !loading; 105 | onClicked: internal.getlist("next"); 106 | } 107 | } 108 | 109 | ScrollDecorator { flickableItem: view; } 110 | } 111 | -------------------------------------------------------------------------------- /qml/AcFun/ClassPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "Component" 4 | import "../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | property int cid; 10 | property string cname; 11 | property variant subclass; 12 | onSubclassChanged: internal.loadModel(); 13 | 14 | title: viewheader.title; 15 | 16 | tools: ToolBarLayout { 17 | ToolButton { 18 | iconSource: "toolbar-back"; 19 | onClicked: pageStack.pop(); 20 | } 21 | ToolButton { 22 | iconSource: "toolbar-refresh"; 23 | onClicked: getlist(); 24 | } 25 | } 26 | 27 | function getlist(){ internal.getlist(); } 28 | 29 | QtObject { 30 | id: internal; 31 | 32 | property int pageNumber: 1; 33 | property int totalNumber: 0; 34 | property int pageSize: 20; 35 | 36 | property int classId; 37 | property string className; 38 | 39 | function setClass(){ 40 | if (subclass){ 41 | var item = subclass[subclassSelector.selectedIndex]; 42 | if (item){ 43 | classId = item.id; 44 | className = item.name; 45 | } 46 | } 47 | } 48 | 49 | function getlist(option){ 50 | loading = true; 51 | var opt = { model: view.model, "class": classId }; 52 | if (view.count === 0) option = "renew"; 53 | option = option || "renew"; 54 | if (option === "renew"){ 55 | opt.renew = true; 56 | } else { 57 | opt.cursor = pageNumber * pageSize; 58 | } 59 | function s(obj){ 60 | loading = false; 61 | pageNumber = obj.pageNo; 62 | totalNumber = obj.totalCount; 63 | pageSize = obj.pageSize; 64 | } 65 | function f(err){ loading = false; signalCenter.showMessage(err); } 66 | Script.getClass(opt, s, f); 67 | } 68 | 69 | function loadModel(){ 70 | var m = subclassSelector.model; 71 | m.clear(); 72 | subclass.forEach(function(value){ 73 | m.append({name: value.name}); 74 | }) 75 | subclassSelector.selectedIndex = 0; 76 | } 77 | } 78 | 79 | SelectionDialog { 80 | id: subclassSelector; 81 | titleText: cname; 82 | model: ListModel {} 83 | onSelectedIndexChanged: internal.setClass(); 84 | onAccepted: internal.getlist(); 85 | } 86 | 87 | ViewHeader { 88 | id: viewheader; 89 | title: page.cname + "-" + internal.className; 90 | ToolButton { 91 | anchors { 92 | right: parent.right; verticalCenter: parent.verticalCenter; 93 | } 94 | iconSource: "toolbar-menu"; 95 | onClicked: subclassSelector.open(); 96 | } 97 | } 98 | 99 | ListView { 100 | id: view; 101 | anchors { fill: parent; topMargin: viewheader.height; } 102 | model: ListModel {} 103 | delegate: CommonDelegate {} 104 | footer: FooterItem { 105 | visible: internal.pageSize * internal.pageNumber < internal.totalNumber; 106 | enabled: !loading; 107 | onClicked: internal.getlist("next"); 108 | } 109 | } 110 | 111 | ScrollDecorator { flickableItem: view; } 112 | } 113 | -------------------------------------------------------------------------------- /qml/gfx/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 27 | 34 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /qml/harmattan/SeriesPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import "Component" 4 | import "SeriesPageCom" as Series 5 | import "../js/main.js" as Script 6 | 7 | MyPage { 8 | id: page; 9 | 10 | property int channelId: 1; 11 | Component.onCompleted: getlist(); 12 | 13 | tools: ToolBarLayout { 14 | ToolIcon { 15 | platformIconId: "toolbar-back"; 16 | onClicked: pageStack.pop(); 17 | } 18 | ToolIcon { 19 | platformIconId: "toolbar-refresh"; 20 | onClicked: getlist(); 21 | } 22 | ToolIcon { 23 | platformIconId: flip.side === Flipable.Front 24 | ? "toolbar-list" : "toolbar-grid"; 25 | onClicked: flip.state = flip.state === "" ? "back" : ""; 26 | } 27 | } 28 | 29 | ViewHeader { 30 | id: viewHeader; 31 | title: "追剧" 32 | } 33 | 34 | ButtonRow { 35 | id: buttonRow; 36 | anchors { left: parent.left; right: parent.right; top: viewHeader.bottom } 37 | Button { 38 | text: "动画" 39 | onClicked: refresh(1); 40 | } 41 | Button { 42 | text: "剧集" 43 | onClicked: refresh(3); 44 | } 45 | Button { 46 | text: "综艺" 47 | onClicked: refresh(4); 48 | } 49 | } 50 | 51 | function refresh(cid){ 52 | if (channelId !== cid){ 53 | channelId = cid; 54 | getlist(); 55 | } 56 | } 57 | 58 | function getlist(){ 59 | loading = true; 60 | var opt = { 61 | channelId: channelId, 62 | model: seriesModel 63 | }; 64 | function s(){ 65 | loading = false; 66 | } 67 | function f(err){ 68 | loading = false; 69 | signalCenter.showMessage(err); 70 | } 71 | Script.getPlaybill(opt, s, f); 72 | } 73 | 74 | ListModel { id: seriesModel; } 75 | 76 | Flipable { 77 | id: flip; 78 | anchors { 79 | left: parent.left; right: parent.right; 80 | top: buttonRow.bottom; bottom: parent.bottom; 81 | } 82 | front: GridView { 83 | id: gridView; 84 | clip: true; 85 | anchors.fill: parent; 86 | cellWidth: app.inPortrait ? width/3 : width/5; 87 | cellHeight: cellWidth/3*4+constant.paddingLarge; 88 | model: seriesModel; 89 | delegate: Series.SeriesDelegate {} 90 | } 91 | back: ListView { 92 | id: listV; 93 | clip: true; 94 | anchors.fill: parent; 95 | model: seriesModel; 96 | delegate: Series.SeriesDelegateL {} 97 | section.property: "day"; 98 | section.delegate: SectionHeader { 99 | title: section; 100 | } 101 | FastScroll { 102 | listView: listV; 103 | } 104 | } 105 | transform: Rotation { 106 | id: rotation; 107 | origin: Qt.vector3d(flip.width/2, flip.height/2, 0); 108 | axis: Qt.vector3d(0, 1, 0); 109 | angle: 0; 110 | } 111 | states: State { 112 | name: "back"; 113 | PropertyChanges { 114 | target: rotation; 115 | angle: 180; 116 | } 117 | } 118 | transitions: Transition { 119 | RotationAnimation { 120 | direction: RotationAnimation.Clockwise; 121 | } 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /qml/harmattan/ACPlayer/VideoLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.meego 1.1 3 | import QtMobility.systeminfo 1.1 4 | import QtMultimediaKit 1.1 5 | 6 | Item { 7 | id: root; 8 | 9 | property alias source: video.source; 10 | property alias duration: video.duration; 11 | property alias timePlayed: video.position; 12 | property int timeRemaining: duration - timePlayed; 13 | property alias volume: video.volume; 14 | 15 | property bool isPlaying: false; 16 | property bool freezing: video.status === Video.Loading; 17 | 18 | signal playbackStarted; 19 | signal loadStarted; 20 | 21 | function play(){ 22 | video.play(); 23 | } 24 | 25 | function pause(){ 26 | video.pause(); 27 | } 28 | 29 | function stop(){ 30 | video.stop(); 31 | } 32 | 33 | function __handleStatusChange(status, playing, position, paused){ 34 | var isVisibleState = status === Video.Buffered || status === Video.EndOfMedia; 35 | var isStalled = status === Video.Stalled; 36 | 37 | // 背景 38 | if ((isVisibleState||isStalled) && !(paused && position === 0)){ 39 | blackBackground.opacity = 0; 40 | } else { 41 | blackBackground.opacity = 1; 42 | } 43 | 44 | // 加载图标 45 | if (!isVisibleState && playing){ 46 | busyIndicator.visible = true; 47 | } else { 48 | busyIndicator.visible = false; 49 | } 50 | 51 | if (status === Video.EndOfMedia){ 52 | video.stop(); 53 | video.position = 0; 54 | } 55 | } 56 | 57 | function __setScreenSaver(){ 58 | if (video.playing && !video.paused){ 59 | screenSaver.setScreenSaverDelayed(true); 60 | } else { 61 | screenSaver.setScreenSaverDelayed(false); 62 | } 63 | } 64 | 65 | ScreenSaver { 66 | id: screenSaver; 67 | } 68 | 69 | Rectangle { 70 | id: videoBackground; 71 | color: "#000000"; 72 | anchors.fill: parent; 73 | } 74 | 75 | Video { 76 | id: video; 77 | 78 | property bool playbackStarted: false; 79 | property bool loaded: false; 80 | 81 | volume: visual.currentVolume; 82 | autoLoad: true; 83 | anchors.fill: parent; 84 | fillMode: Video.PreserveAspectFit; 85 | onSourceChanged: play(); 86 | onPlayingChanged: { 87 | root.isPlaying = playing; 88 | __setScreenSaver(); 89 | __handleStatusChange(status, isPlaying, position, paused); 90 | } 91 | onPausedChanged: { 92 | root.isPlaying = !paused; 93 | __setScreenSaver(); 94 | __handleStatusChange(status, isPlaying, position, paused); 95 | } 96 | onStatusChanged: { 97 | if (status === Video.Buffered && !video.playbackStarted){ 98 | video.playbackStarted = true; 99 | root.playbackStarted(); 100 | } 101 | if (status === Video.Loading && !video.loaded){ 102 | video.loaded = true; 103 | root.loadStarted(); 104 | } 105 | __handleStatusChange(status, isPlaying, position, paused); 106 | } 107 | } 108 | 109 | Rectangle { 110 | id: blackBackground; 111 | anchors.fill: parent; 112 | color: "#000000"; 113 | } 114 | 115 | BusyIndicator { 116 | id: busyIndicator; 117 | anchors.centerIn: blackBackground; 118 | running: true; 119 | visible: false; 120 | platformStyle: BusyIndicatorStyle { 121 | inverted: true; 122 | size: "large"; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /qml/AcFun/ACPlayer/VideoLayer.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1; 3 | import QtMobility.systeminfo 1.1 4 | import QtMultimediaKit 1.1 5 | 6 | Item { 7 | id: root; 8 | 9 | property alias source: video.source; 10 | property alias duration: video.duration; 11 | property alias timePlayed: video.position; 12 | property int timeRemaining: duration - timePlayed; 13 | property alias volume: video.volume; 14 | 15 | property bool isPlaying: false; 16 | property bool freezing: video.status === Video.Loading; 17 | 18 | signal playbackStarted; 19 | signal loadStarted; 20 | 21 | function play(){ 22 | video.play(); 23 | } 24 | 25 | function pause(){ 26 | video.pause(); 27 | } 28 | 29 | function stop(){ 30 | video.stop(); 31 | } 32 | 33 | function forward(){ 34 | timePlayed = Math.min(timePlayed + 15000, duration); 35 | } 36 | 37 | function backwards(){ 38 | timePlayed = Math.max(timePlayed - 15000, 0); 39 | } 40 | 41 | function __handleStatusChange(status, playing, position, paused){ 42 | var isVisibleState = status === Video.Buffered || status === Video.EndOfMedia; 43 | var isStalled = status === Video.Stalled; 44 | 45 | // 背景 46 | if ((isVisibleState||isStalled) && !(paused && position === 0)){ 47 | blackBackground.opacity = 0; 48 | } else { 49 | blackBackground.opacity = 1; 50 | } 51 | 52 | // 加载图标 53 | if (!isVisibleState && playing){ 54 | busyIndicator.opacity = 1; 55 | } else { 56 | busyIndicator.opacity = 0; 57 | } 58 | 59 | if (status === Video.EndOfMedia){ 60 | video.stop(); 61 | video.position = 0; 62 | } 63 | } 64 | 65 | function __setScreenSaver(){ 66 | if (video.playing && !video.paused){ 67 | screenSaver.setScreenSaverDelayed(true); 68 | } else { 69 | screenSaver.setScreenSaverDelayed(false); 70 | } 71 | } 72 | 73 | ScreenSaver { 74 | id: screenSaver; 75 | } 76 | 77 | Rectangle { 78 | id: videoBackground; 79 | color: "#000000"; 80 | anchors.fill: parent; 81 | } 82 | 83 | Video { 84 | id: video; 85 | 86 | property bool playbackStarted: false; 87 | property bool loaded: false; 88 | 89 | volume: visual.currentVolume; 90 | autoLoad: true; 91 | anchors.fill: parent; 92 | fillMode: Video.PreserveAspectFit; 93 | onSourceChanged: play(); 94 | onPlayingChanged: { 95 | root.isPlaying = playing; 96 | __setScreenSaver(); 97 | __handleStatusChange(status, isPlaying, position, paused); 98 | } 99 | onPausedChanged: { 100 | root.isPlaying = !paused; 101 | __setScreenSaver(); 102 | __handleStatusChange(status, isPlaying, position, paused); 103 | } 104 | onStatusChanged: { 105 | if (status === Video.Buffered && !video.playbackStarted){ 106 | video.playbackStarted = true; 107 | root.playbackStarted(); 108 | } 109 | if (status === Video.Loading && !video.loaded){ 110 | video.loaded = true; 111 | root.loadStarted(); 112 | } 113 | __handleStatusChange(status, isPlaying, position, paused); 114 | } 115 | } 116 | 117 | Rectangle { 118 | id: blackBackground; 119 | anchors.fill: parent; 120 | color: "#000000"; 121 | } 122 | 123 | BusyIndicator { 124 | id: busyIndicator; 125 | anchors.centerIn: blackBackground; 126 | height: visual.busyIndicatorHeight; 127 | width: visual.busyIndicatorWidth; 128 | running: true; 129 | opacity: 0; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /qml/AcFun/UserPageCom/FavPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 1.1 2 | import com.nokia.symbian 1.1 3 | import "../Component" 4 | import "../../js/main.js" as Script 5 | 6 | MyPage { 7 | id: page; 8 | 9 | tools: ToolBarLayout { 10 | ToolButton { 11 | iconSource: "toolbar-back"; 12 | onClicked: pageStack.pop(); 13 | } 14 | ToolButton { 15 | iconSource: "toolbar-refresh"; 16 | onClicked: internal.getlist(); 17 | } 18 | ToolButton { 19 | iconSource: internal.deleteMode ? "../../gfx/ok.svg" 20 | : "toolbar-delete"; 21 | onClicked: internal.deleteMode = !internal.deleteMode; 22 | } 23 | } 24 | 25 | QtObject { 26 | id: internal; 27 | 28 | property int pageNumber: 1; 29 | property int totalNumber: 0; 30 | property int pageSize: 20; 31 | property bool deleteMode: false; 32 | 33 | function getlist(option){ 34 | loading = true; 35 | var opt = { model: view.model }; 36 | if (view.count === 0) option = "renew"; 37 | option = option || "renew"; 38 | if (option === "renew"){ 39 | opt.renew = true; 40 | } else { 41 | opt.cursor = pageNumber * pageSize; 42 | } 43 | function s(obj){ 44 | loading = false; 45 | pageNumber = obj.pageNo; 46 | totalNumber = obj.totalCount; 47 | pageSize = obj.pageSize; 48 | } 49 | function f(err){ 50 | loading = false; 51 | signalCenter.showMessage(err); 52 | } 53 | Script.getFavVideos(opt, s, f); 54 | } 55 | 56 | function unfav(idx, acId){ 57 | var url = Script.AcApi.users; 58 | url += "/"+acsettings.userId; 59 | url += "/fav/videos/"+acId; 60 | url += "?access_token="+acsettings.accessToken; 61 | helperListener.index = idx; 62 | helperListener.reqUrl = url; 63 | networkHelper.createDeleteRequest(url); 64 | loading = true; 65 | } 66 | } 67 | 68 | Connections { 69 | id: helperListener; 70 | property string reqUrl; 71 | property int index; 72 | target: networkHelper; 73 | onRequestFinished: { 74 | if (url.toString() === helperListener.reqUrl){ 75 | loading = false; 76 | view.model.remove(helperListener.index); 77 | } 78 | } 79 | onRequestFailed: { 80 | if (url.toString() === helperListener.reqUrl){ 81 | loading = false; 82 | } 83 | } 84 | } 85 | 86 | ViewHeader { 87 | id: viewHeader; 88 | title: page.title; 89 | } 90 | ListView { 91 | id: view; 92 | anchors { fill: parent; topMargin: viewHeader.height; } 93 | model: ListModel {} 94 | delegate: CommonDelegate { 95 | Button { 96 | anchors { 97 | right: parent.right; 98 | verticalCenter: parent.verticalCenter; 99 | } 100 | enabled: !loading; 101 | width: height; 102 | iconSource: privateStyle.toolBarIconPath("toolbar-delete"); 103 | visible: internal.deleteMode; 104 | onClicked: internal.unfav(index, acId); 105 | } 106 | } 107 | footer: FooterItem { 108 | visible: internal.pageSize * internal.pageNumber < internal.totalNumber; 109 | enabled: !loading; 110 | onClicked: internal.getlist("next"); 111 | } 112 | } 113 | ScrollDecorator { flickableItem: view; } 114 | 115 | Component.onCompleted: internal.getlist(); 116 | } 117 | --------------------------------------------------------------------------------